From 0b77af7ede97b99fb9b4a77244e4d1e9fcd7cdaa Mon Sep 17 00:00:00 2001 From: 1foxy2 <127777030+1foxy2@users.noreply.github.com> Date: Tue, 3 Dec 2024 17:54:59 +0100 Subject: [PATCH] Port to 1.21.4 (#317) * Port to 1.21.4 * Return lod * Return isBlockItem, update to rc3 * Remove transformation != null check * Port neoforge part * Update publish * Maybe fix workflow * Maybe fix workflow 2 * Maybe fix workflow 3 * 1.21.4 --- .github/workflows/publish.yml | 9 +- .../src/main/groovy/multiloader-common.gradle | 2 - .../moreculling/api/model/BakedOpacity.java | 6 + ...java => ExtendedItemStackRenderState.java} | 16 +-- .../blockentity/SignRenderer_textMixin.java | 12 +- .../cullshape/BaseTorchBlock_voxelMixin.java | 27 ++++ .../entities/ItemFrameRenderer_cullMixin.java | 32 ++--- .../mixin/models/BuiltInModel_cacheMixin.java | 65 --------- .../models/DelegateBakedModel_cullMixin.java | 20 ++- .../models/SimpleBakedModel_cacheMixin.java | 12 ++ .../cullshape/BlockModel_cullShapeMixin.java | 73 +--------- .../renderers/ItemRenderer_apiMixin.java | 69 ---------- .../ItemRenderer_faceCullingMixin.java | 92 ++++++++++++- .../ItemStackRenderState_apiMixin.java | 27 ++++ ...ItemStackRenderState_faceCullingMixin.java | 31 +++++ .../renderers/LayerRenderState_apiMixin.java | 46 +++++++ .../states/ItemRendererStates.java | 2 + .../fxco/moreculling/utils/CullingUtils.java | 3 +- .../resources/META-INF/accesstransformer.cfg | 1 + .../main/resources/moreculling.accesswidener | 3 +- .../main/resources/moreculling.mixins.json | 11 +- fabric/build.gradle | 2 +- .../ForwardingBakedModel_compatMixin.java | 46 ------- .../models/ItemModelGenerator_cullMixin.java | 31 +++++ .../BlockModel_fabricCullShapeMixin.java | 85 ++++++++++++ .../ItemRenderer_fabricFaceCullingMixin.java | 124 ----------------- .../resources/moreculling.fabric.mixins.json | 4 +- gradle.properties | 13 +- neoforge/build.gradle | 5 +- .../models/ItemModelGenerator_cullMixin.java | 29 ++++ .../BlockModel_neoforgeCullShapeMixin.java | 87 ++++++++++++ ...IBakedModelExtension_faceCullingMixin.java | 35 +++++ ...ItemRenderer_neoforgeFaceCullingMixin.java | 125 ------------------ .../moreculling.neoforge.mixins.json | 5 +- 34 files changed, 577 insertions(+), 573 deletions(-) rename common/src/main/java/ca/fxco/moreculling/api/renderers/{ExtendedItemRenderer.java => ExtendedItemStackRenderState.java} (83%) create mode 100644 common/src/main/java/ca/fxco/moreculling/mixin/blocks/cullshape/BaseTorchBlock_voxelMixin.java delete mode 100644 common/src/main/java/ca/fxco/moreculling/mixin/models/BuiltInModel_cacheMixin.java rename neoforge/src/main/java/ca/fxco/moreculling/mixin/models/BakedModelWrapper_compatMixin.java => common/src/main/java/ca/fxco/moreculling/mixin/models/DelegateBakedModel_cullMixin.java (59%) delete mode 100644 common/src/main/java/ca/fxco/moreculling/mixin/renderers/ItemRenderer_apiMixin.java create mode 100644 common/src/main/java/ca/fxco/moreculling/mixin/renderers/ItemStackRenderState_apiMixin.java create mode 100644 common/src/main/java/ca/fxco/moreculling/mixin/renderers/ItemStackRenderState_faceCullingMixin.java create mode 100644 common/src/main/java/ca/fxco/moreculling/mixin/renderers/LayerRenderState_apiMixin.java delete mode 100644 fabric/src/main/java/ca/fxco/moreculling/mixin/models/ForwardingBakedModel_compatMixin.java create mode 100644 fabric/src/main/java/ca/fxco/moreculling/mixin/models/ItemModelGenerator_cullMixin.java create mode 100644 fabric/src/main/java/ca/fxco/moreculling/mixin/models/cullshape/BlockModel_fabricCullShapeMixin.java delete mode 100644 fabric/src/main/java/ca/fxco/moreculling/mixin/renderers/ItemRenderer_fabricFaceCullingMixin.java create mode 100644 neoforge/src/main/java/ca/fxco/moreculling/mixin/models/ItemModelGenerator_cullMixin.java create mode 100644 neoforge/src/main/java/ca/fxco/moreculling/mixin/models/cullshape/BlockModel_neoforgeCullShapeMixin.java create mode 100644 neoforge/src/main/java/ca/fxco/moreculling/mixin/renderers/IBakedModelExtension_faceCullingMixin.java delete mode 100644 neoforge/src/main/java/ca/fxco/moreculling/mixin/renderers/ItemRenderer_neoforgeFaceCullingMixin.java diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 49ed9d26..b9224b43 100755 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -24,10 +24,9 @@ jobs: with: files: neoforge/build/libs/!(*-@(dev|sources|api|javadoc)).jar github-files: neoforge/build/libs/*-@(dev|sources|api|javadoc).jar - version-type: release + version-type: beta game-versions: | - 1.21.2 - 1.21.3 + 1.21.4 game-version-filter: releases dependencies: | cloth-config(required){modrinth:9s6osm5g}{curseforge:348521}#(ignore:github) @@ -63,12 +62,10 @@ jobs: github-files: fabric/build/libs/*-@(dev|sources|api|javadoc).jar version-type: beta game-versions: | - 1.21.2 - 1.21.3 + 1.21.4 game-version-filter: releases dependencies: | cloth-config(required){modrinth:9s6osm5g}{curseforge:348521}#(ignore:github) - sodium@mc1.21-0.5.11(incompatible){modrinth:AANobbMI}#(ignore:github)(ignore:curseforge) modrinth-featured: true modrinth-id: 51shyZVL modrinth-token: ${{ secrets.MODRINTH_TOKEN }} diff --git a/buildSrc/src/main/groovy/multiloader-common.gradle b/buildSrc/src/main/groovy/multiloader-common.gradle index a82ef818..fc2ff799 100644 --- a/buildSrc/src/main/groovy/multiloader-common.gradle +++ b/buildSrc/src/main/groovy/multiloader-common.gradle @@ -34,8 +34,6 @@ repositories { filter { includeGroup('org.parchmentmc.data') includeGroup "maven.modrinth" - includeModule("net.neoforged", "testframework") - includeModule("net.neoforged", "neoforge") } } maven { //AutoConfig diff --git a/common/src/main/java/ca/fxco/moreculling/api/model/BakedOpacity.java b/common/src/main/java/ca/fxco/moreculling/api/model/BakedOpacity.java index 363e0483..dbd556d5 100644 --- a/common/src/main/java/ca/fxco/moreculling/api/model/BakedOpacity.java +++ b/common/src/main/java/ca/fxco/moreculling/api/model/BakedOpacity.java @@ -85,4 +85,10 @@ public interface BakedOpacity { default boolean moreculling$canSetCullingShape() { return false; } + + default boolean moreculling$isItem() { + return false; + } + + default void moreculling$setIsItem() {} } diff --git a/common/src/main/java/ca/fxco/moreculling/api/renderers/ExtendedItemRenderer.java b/common/src/main/java/ca/fxco/moreculling/api/renderers/ExtendedItemStackRenderState.java similarity index 83% rename from common/src/main/java/ca/fxco/moreculling/api/renderers/ExtendedItemRenderer.java rename to common/src/main/java/ca/fxco/moreculling/api/renderers/ExtendedItemStackRenderState.java index e68b2016..225f89a7 100644 --- a/common/src/main/java/ca/fxco/moreculling/api/renderers/ExtendedItemRenderer.java +++ b/common/src/main/java/ca/fxco/moreculling/api/renderers/ExtendedItemStackRenderState.java @@ -4,23 +4,22 @@ import com.mojang.blaze3d.vertex.VertexConsumer; import net.minecraft.client.Camera; import net.minecraft.client.renderer.MultiBufferSource; -import net.minecraft.client.renderer.entity.ItemRenderer; import net.minecraft.client.renderer.entity.state.ItemFrameRenderState; +import net.minecraft.client.renderer.item.ItemStackRenderState; import net.minecraft.client.resources.model.BakedModel; import net.minecraft.core.Direction; -import net.minecraft.world.item.ItemStack; import org.jetbrains.annotations.Nullable; /** * This interface allows you to call the MoreCulling methods used for item rendering. * This gives you access to the custom MoreCulling rendering methods, in order to allow everyone to benefit from the * performance boost that MoreCulling can offer.
- * Use these methods over ones provided in {@link ItemRenderer} + * Use these methods over ones provided in {@link ItemStackRenderState} * * @since 0.8.0 */ -public interface ExtendedItemRenderer { +public interface ExtendedItemStackRenderState { /** * This will render a baked item model without a specific face. (Item Frame) @@ -28,7 +27,7 @@ public interface ExtendedItemRenderer { * * @since 0.25.0 */ - void moreculling$renderBakedItemModelWithoutFace(BakedModel model, ItemStack stack, int light, int overlay, + void moreculling$renderBakedItemModelWithoutFace(BakedModel model, int light, int overlay, PoseStack poseStack, VertexConsumer vertices, @Nullable Direction withoutFace); @@ -38,7 +37,7 @@ public interface ExtendedItemRenderer { * * @since 0.25.0 */ - void moreculling$renderBakedItemModelForFace(BakedModel model, ItemStack stack, int light, int overlay, + void moreculling$renderBakedItemModelForFace(BakedModel model, int light, int overlay, PoseStack poseStack, VertexConsumer vertices, Direction face); /** @@ -47,16 +46,17 @@ public interface ExtendedItemRenderer { * * @since 0.25.0 */ - void moreculling$renderBakedItemModelOnly3Faces(BakedModel model, ItemStack stack, int light, int overlay, + void moreculling$renderBakedItemModelOnly3Faces(BakedModel model, int light, int overlay, PoseStack poseStack, VertexConsumer vertices, Direction faceX, Direction faceY, Direction faceZ); + /** * This will render an item as if it was in an item frame like MoreCulling, it will automatically include all of * MoreCulling's optimizations. * * @since 0.25.0 */ - void moreculling$renderItemFrameItem(ItemStack stack, PoseStack poseStack, MultiBufferSource multiBufferSource, + void moreculling$renderItemFrameItem(PoseStack poseStack, MultiBufferSource multiBufferSource, int light, ItemFrameRenderState frame, Camera camera); } \ No newline at end of file diff --git a/common/src/main/java/ca/fxco/moreculling/mixin/blockentity/SignRenderer_textMixin.java b/common/src/main/java/ca/fxco/moreculling/mixin/blockentity/SignRenderer_textMixin.java index 0e2f1a63..d50364a5 100644 --- a/common/src/main/java/ca/fxco/moreculling/mixin/blockentity/SignRenderer_textMixin.java +++ b/common/src/main/java/ca/fxco/moreculling/mixin/blockentity/SignRenderer_textMixin.java @@ -8,7 +8,7 @@ import net.minecraft.client.Minecraft; import net.minecraft.client.model.Model; import net.minecraft.client.renderer.MultiBufferSource; -import net.minecraft.client.renderer.blockentity.SignRenderer; +import net.minecraft.client.renderer.blockentity.AbstractSignRenderer; import net.minecraft.core.BlockPos; import net.minecraft.core.Direction; import net.minecraft.world.level.block.StandingSignBlock; @@ -23,7 +23,7 @@ import static ca.fxco.moreculling.utils.CullingUtils.shouldHideWallSignText; import static ca.fxco.moreculling.utils.MathUtils.ONE_SIGN_ROTATION; -@Mixin(SignRenderer.class) +@Mixin(AbstractSignRenderer.class) public class SignRenderer_textMixin { @WrapWithCondition( @@ -34,14 +34,14 @@ public class SignRenderer_textMixin { "Lnet/minecraft/world/level/block/state/properties/WoodType;Lnet/minecraft/client/model/Model;)V", at = @At( value = "INVOKE", - target = "Lnet/minecraft/client/renderer/blockentity/SignRenderer;renderSignText(" + + target = "Lnet/minecraft/client/renderer/blockentity/AbstractSignRenderer;renderSignText(" + "Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/entity/SignText;" + "Lcom/mojang/blaze3d/vertex/PoseStack;" + "Lnet/minecraft/client/renderer/MultiBufferSource;IIIZ)V", ordinal = 0 ) ) - private boolean moreculling$cullFrontSignText(SignRenderer renderer, BlockPos pos, SignText text, + private boolean moreculling$cullFrontSignText(AbstractSignRenderer renderer, BlockPos pos, SignText text, PoseStack poseStack, MultiBufferSource mutliBufferSource, int i, int j, int i2, boolean l, @Local(argsOnly = true) BlockState state, @@ -57,14 +57,14 @@ public class SignRenderer_textMixin { "Lnet/minecraft/world/level/block/state/properties/WoodType;Lnet/minecraft/client/model/Model;)V", at = @At( value = "INVOKE", - target = "Lnet/minecraft/client/renderer/blockentity/SignRenderer;renderSignText(" + + target = "Lnet/minecraft/client/renderer/blockentity/AbstractSignRenderer;renderSignText(" + "Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/block/entity/SignText;" + "Lcom/mojang/blaze3d/vertex/PoseStack;" + "Lnet/minecraft/client/renderer/MultiBufferSource;IIIZ)V", ordinal = 1 ) ) - private boolean moreculling$cullBackSignText(SignRenderer renderer, BlockPos pos, SignText text, + private boolean moreculling$cullBackSignText(AbstractSignRenderer renderer, BlockPos pos, SignText text, PoseStack poseStack, MultiBufferSource mutliBufferSource, int i, int j, int i2, boolean l, @Local(argsOnly = true) BlockState state, diff --git a/common/src/main/java/ca/fxco/moreculling/mixin/blocks/cullshape/BaseTorchBlock_voxelMixin.java b/common/src/main/java/ca/fxco/moreculling/mixin/blocks/cullshape/BaseTorchBlock_voxelMixin.java new file mode 100644 index 00000000..2d46d702 --- /dev/null +++ b/common/src/main/java/ca/fxco/moreculling/mixin/blocks/cullshape/BaseTorchBlock_voxelMixin.java @@ -0,0 +1,27 @@ +package ca.fxco.moreculling.mixin.blocks.cullshape; + +import ca.fxco.moreculling.api.block.MoreBlockCulling; +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.BlockGetter; +import net.minecraft.world.level.block.*; +import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.shapes.CollisionContext; +import net.minecraft.world.phys.shapes.Shapes; +import net.minecraft.world.phys.shapes.VoxelShape; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; + +@Mixin(BaseTorchBlock.class) +public abstract class BaseTorchBlock_voxelMixin extends Block implements MoreBlockCulling { + @Unique + private static final VoxelShape moreculling$occlusionShape = Block.box(7.0, 0.0, 7.0, 9.0, 10.0, 9.0); + + protected BaseTorchBlock_voxelMixin(Properties settings) { + super(settings); + } + + @Override + public VoxelShape getOcclusionShape(BlockState state) { + return moreculling$occlusionShape; + } +} diff --git a/common/src/main/java/ca/fxco/moreculling/mixin/entities/ItemFrameRenderer_cullMixin.java b/common/src/main/java/ca/fxco/moreculling/mixin/entities/ItemFrameRenderer_cullMixin.java index eed69a88..69143d28 100644 --- a/common/src/main/java/ca/fxco/moreculling/mixin/entities/ItemFrameRenderer_cullMixin.java +++ b/common/src/main/java/ca/fxco/moreculling/mixin/entities/ItemFrameRenderer_cullMixin.java @@ -3,7 +3,7 @@ import ca.fxco.moreculling.MoreCulling; import ca.fxco.moreculling.api.map.MapOpacity; import ca.fxco.moreculling.api.renderers.ExtendedBlockModelRenderer; -import ca.fxco.moreculling.api.renderers.ExtendedItemRenderer; +import ca.fxco.moreculling.api.renderers.ExtendedItemStackRenderState; import ca.fxco.moreculling.utils.CullingUtils; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.math.Axis; @@ -16,14 +16,13 @@ import net.minecraft.client.renderer.entity.EntityRenderer; import net.minecraft.client.renderer.entity.EntityRendererProvider; import net.minecraft.client.renderer.entity.ItemFrameRenderer; -import net.minecraft.client.renderer.entity.ItemRenderer; import net.minecraft.client.renderer.entity.state.ItemFrameRenderState; +import net.minecraft.client.renderer.item.ItemStackRenderState; import net.minecraft.client.renderer.texture.OverlayTexture; import net.minecraft.client.resources.model.ModelManager; import net.minecraft.client.resources.model.ModelResourceLocation; import net.minecraft.core.Direction; import net.minecraft.world.entity.decoration.ItemFrame; -import net.minecraft.world.item.ItemStack; import net.minecraft.world.item.MapItem; import net.minecraft.world.level.saveddata.maps.MapId; import net.minecraft.world.level.saveddata.maps.MapItemSavedData; @@ -50,16 +49,14 @@ public abstract class ItemFrameRenderer_cullMixin extends E @Final private BlockRenderDispatcher blockRenderer; - @Shadow - @Final - private ItemRenderer itemRenderer; + @Shadow @Final private MapRenderer mapRenderer; @Shadow - protected abstract ModelResourceLocation getFrameModelResourceLoc(boolean isGlow, ItemStack stack); - - @Shadow protected abstract int getLightVal(boolean par1, int par2, int par3); + private static ModelResourceLocation getFrameModelResourceLocation(ItemFrameRenderState itemFrameRenderState) { + return null; + } - @Shadow @Final private MapRenderer mapRenderer; + @Shadow protected abstract int getLightCoords(boolean bl, int i, int j); protected ItemFrameRenderer_cullMixin(EntityRendererProvider.Context ctx) { super(ctx); @@ -107,9 +104,9 @@ protected ItemFrameRenderer_cullMixin(EntityRendererProvider.Context ctx) { poseStack.mulPose(Axis.XP.rotationDegrees(xRot)); poseStack.mulPose(Axis.YP.rotationDegrees(yRot)); - ItemStack itemStack = itemFrameState.itemStack; + ItemStackRenderState itemStackState = itemFrameState.item; boolean skipFrontRender = false; - if (!itemStack.isEmpty()) { + if (!itemStackState.isEmpty()) { poseStack.pushPose(); MapId mapIdComponent = itemFrameState.mapId; if (mapIdComponent != null) { @@ -137,7 +134,7 @@ protected ItemFrameRenderer_cullMixin(EntityRendererProvider.Context ctx) { poseStack, multiBufferSource, true, - this.getLightVal( + this.getLightCoords( itemFrameState.isGlowFrame, LightTexture.FULL_SKY | 0xD2, i @@ -145,16 +142,15 @@ protected ItemFrameRenderer_cullMixin(EntityRendererProvider.Context ctx) { ); } } - } else if (itemFrameState.itemModel != null) { + } else if (!itemStackState.isEmpty()) { poseStack.translate(0.0, 0.0, itemFrameState.isInvisible ? 0.5 : 0.4375); poseStack.mulPose(Axis.ZP.rotationDegrees( (float) itemFrameState.rotation * 360.0f / 8.0f) ); - int l = this.getLightVal(itemFrameState.isGlowFrame, LightTexture.FULL_BRIGHT, i); + int l = this.getLightCoords(itemFrameState.isGlowFrame, LightTexture.FULL_BRIGHT, i); poseStack.scale(0.5f, 0.5f, 0.5f); // Use extended item renderer here - ((ExtendedItemRenderer) this.itemRenderer).moreculling$renderItemFrameItem( - itemStack, + ((ExtendedItemStackRenderState) itemStackState).moreculling$renderItemFrameItem( poseStack, multiBufferSource, l, @@ -166,7 +162,7 @@ protected ItemFrameRenderer_cullMixin(EntityRendererProvider.Context ctx) { } if (!itemFrameState.isInvisible) { // Render Item Frame block model ModelManager modelManager = this.blockRenderer.getBlockModelShaper().getModelManager(); - ModelResourceLocation modelResourceLocation = this.getFrameModelResourceLoc(itemFrameState.isGlowFrame, itemStack); + ModelResourceLocation modelResourceLocation = getFrameModelResourceLocation(itemFrameState); poseStack.translate(-0.5, -0.5, -0.5); var modelRenderer = (ExtendedBlockModelRenderer) this.blockRenderer.getModelRenderer(); if (CullingUtils.shouldCullBack(itemFrameState)) { diff --git a/common/src/main/java/ca/fxco/moreculling/mixin/models/BuiltInModel_cacheMixin.java b/common/src/main/java/ca/fxco/moreculling/mixin/models/BuiltInModel_cacheMixin.java deleted file mode 100644 index 001c59ea..00000000 --- a/common/src/main/java/ca/fxco/moreculling/mixin/models/BuiltInModel_cacheMixin.java +++ /dev/null @@ -1,65 +0,0 @@ -package ca.fxco.moreculling.mixin.models; - -import ca.fxco.moreculling.api.model.BakedOpacity; -import ca.fxco.moreculling.api.sprite.SpriteOpacity; -import net.minecraft.client.renderer.block.model.ItemTransforms; -import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.client.resources.model.BuiltInModel; -import net.minecraft.core.Direction; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.phys.shapes.VoxelShape; -import org.jetbrains.annotations.Nullable; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; -import org.spongepowered.asm.mixin.Unique; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; - -@Mixin(BuiltInModel.class) -public abstract class BuiltInModel_cacheMixin implements BakedOpacity { - - @Shadow - @Final - private TextureAtlasSprite particleTexture; - - @Unique - private boolean moreculling$hasTranslucency; - @Unique - private @Nullable VoxelShape moreculling$cullVoxelShape; - - @Override - public boolean moreculling$hasTextureTranslucency(@Nullable BlockState state, @Nullable Direction direction) { - return moreculling$hasTranslucency; - } - - @Override - public void moreculling$resetTranslucencyCache() { - moreculling$hasTranslucency = ((SpriteOpacity) particleTexture).moreculling$hasTranslucency(); - } - - @Override - public @Nullable VoxelShape moreculling$getCullingShape(BlockState state) { - return this.moreculling$cullVoxelShape; - } - - @Override - public void moreculling$setCullingShape(VoxelShape cullingShape) { - this.moreculling$cullVoxelShape = cullingShape; - } - - @Override - public boolean moreculling$canSetCullingShape() { - return true; - } - - @Inject( - method = "", - at = @At("RETURN") - ) - private void moreculling$onInit(ItemTransforms transformation, TextureAtlasSprite sprite, - boolean sideLit, CallbackInfo ci) { - moreculling$resetTranslucencyCache(); - } -} diff --git a/neoforge/src/main/java/ca/fxco/moreculling/mixin/models/BakedModelWrapper_compatMixin.java b/common/src/main/java/ca/fxco/moreculling/mixin/models/DelegateBakedModel_cullMixin.java similarity index 59% rename from neoforge/src/main/java/ca/fxco/moreculling/mixin/models/BakedModelWrapper_compatMixin.java rename to common/src/main/java/ca/fxco/moreculling/mixin/models/DelegateBakedModel_cullMixin.java index 49de7f90..dd6a94af 100644 --- a/neoforge/src/main/java/ca/fxco/moreculling/mixin/models/BakedModelWrapper_compatMixin.java +++ b/common/src/main/java/ca/fxco/moreculling/mixin/models/DelegateBakedModel_cullMixin.java @@ -2,44 +2,42 @@ import ca.fxco.moreculling.api.model.BakedOpacity; import net.minecraft.client.resources.model.BakedModel; +import net.minecraft.client.resources.model.DelegateBakedModel; import net.minecraft.core.Direction; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.phys.shapes.VoxelShape; -import net.neoforged.neoforge.client.model.BakedModelWrapper; import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; -@Mixin(BakedModelWrapper.class) -public class BakedModelWrapper_compatMixin implements BakedOpacity { +@Mixin(DelegateBakedModel.class) +public class DelegateBakedModel_cullMixin implements BakedOpacity { - @Final - @Shadow - protected BakedModel originalModel; + @Shadow @Final protected BakedModel parent; @Override public boolean moreculling$hasTextureTranslucency(@Nullable BlockState state, @Nullable Direction direction) { - return ((BakedOpacity) originalModel).moreculling$hasTextureTranslucency(state, direction); + return ((BakedOpacity) parent).moreculling$hasTextureTranslucency(state, direction); } @Override public void moreculling$resetTranslucencyCache() { - ((BakedOpacity) originalModel).moreculling$resetTranslucencyCache(); + ((BakedOpacity) parent).moreculling$resetTranslucencyCache(); } @Override public @Nullable VoxelShape moreculling$getCullingShape(BlockState state) { - return ((BakedOpacity) originalModel).moreculling$getCullingShape(state); + return ((BakedOpacity) parent).moreculling$getCullingShape(state); } @Override public void moreculling$setCullingShape(VoxelShape cullingShape) { - ((BakedOpacity) originalModel).moreculling$setCullingShape(cullingShape); + ((BakedOpacity) parent).moreculling$setCullingShape(cullingShape); } @Override public boolean moreculling$canSetCullingShape() { - return ((BakedOpacity) originalModel).moreculling$canSetCullingShape(); + return ((BakedOpacity) parent).moreculling$canSetCullingShape(); } } diff --git a/common/src/main/java/ca/fxco/moreculling/mixin/models/SimpleBakedModel_cacheMixin.java b/common/src/main/java/ca/fxco/moreculling/mixin/models/SimpleBakedModel_cacheMixin.java index d158dd97..77832740 100644 --- a/common/src/main/java/ca/fxco/moreculling/mixin/models/SimpleBakedModel_cacheMixin.java +++ b/common/src/main/java/ca/fxco/moreculling/mixin/models/SimpleBakedModel_cacheMixin.java @@ -32,6 +32,8 @@ public abstract class SimpleBakedModel_cacheMixin implements BakedOpacity { private final DirectionBits moreculling$solidFaces = new DirectionBits(); @Unique private @Nullable VoxelShape moreculling$cullVoxelShape; + @Unique + private @Nullable boolean moreculling$isItem = false; @Override public boolean moreculling$hasTextureTranslucency(@Nullable BlockState state, @Nullable Direction direction) { @@ -80,4 +82,14 @@ public abstract class SimpleBakedModel_cacheMixin implements BakedOpacity { public boolean moreculling$canSetCullingShape() { return true; } + + @Override + public boolean moreculling$isItem() { + return moreculling$isItem; + } + + @Override + public void moreculling$setIsItem() { + moreculling$isItem = true; + } } diff --git a/common/src/main/java/ca/fxco/moreculling/mixin/models/cullshape/BlockModel_cullShapeMixin.java b/common/src/main/java/ca/fxco/moreculling/mixin/models/cullshape/BlockModel_cullShapeMixin.java index 9b8623c8..e2a885f2 100644 --- a/common/src/main/java/ca/fxco/moreculling/mixin/models/cullshape/BlockModel_cullShapeMixin.java +++ b/common/src/main/java/ca/fxco/moreculling/mixin/models/cullshape/BlockModel_cullShapeMixin.java @@ -1,45 +1,32 @@ package ca.fxco.moreculling.mixin.models.cullshape; -import ca.fxco.moreculling.api.model.BakedOpacity; import ca.fxco.moreculling.api.model.CullShapeElement; import ca.fxco.moreculling.api.model.ExtendedUnbakedModel; import com.google.gson.Gson; import com.google.gson.GsonBuilder; -import com.mojang.math.Transformation; import net.minecraft.client.renderer.block.model.BlockElement; import net.minecraft.client.renderer.block.model.BlockElementFace; import net.minecraft.client.renderer.block.model.BlockModel; -import net.minecraft.client.renderer.texture.TextureAtlasSprite; -import net.minecraft.client.resources.model.BakedModel; -import net.minecraft.client.resources.model.Material; -import net.minecraft.client.resources.model.ModelState; -import net.minecraft.core.Direction; +import net.minecraft.client.resources.model.UnbakedModel; import net.minecraft.resources.ResourceLocation; -import net.minecraft.world.level.block.Block; -import net.minecraft.world.phys.shapes.Shapes; -import net.minecraft.world.phys.shapes.VoxelShape; import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Redirect; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import java.util.List; -import java.util.Map; -import java.util.function.Function; @Mixin(BlockModel.class) public abstract class BlockModel_cullShapeMixin implements ExtendedUnbakedModel { @Shadow @Nullable - protected BlockModel parent; + private UnbakedModel parent; @Shadow - public abstract List getElements(); + abstract List getElements(); @Unique @Nullable @@ -88,7 +75,7 @@ public abstract class BlockModel_cullShapeMixin implements ExtendedUnbakedModel return builder.registerTypeAdapter(CullShapeElement.class, new CullShapeElement.Deserializer()).create(); } - @Redirect( + /*@Redirect( method = {"bake(Ljava/util/function/Function;" + "Lnet/minecraft/client/resources/model/ModelState;" + "Z)Lnet/minecraft/client/resources/model/BakedModel;"}, @@ -99,55 +86,5 @@ public abstract class BlockModel_cullShapeMixin implements ExtendedUnbakedModel ) private Object moreculling$overrideFaceData(Map map, Object direction) { return moreculling$modifyElementFace(map.get((Direction) direction)); - } - - @Inject( - method = "bake(Ljava/util/function/Function;" + - "Lnet/minecraft/client/resources/model/ModelState;" + - "Z)Lnet/minecraft/client/resources/model/BakedModel;", - at = @At( - value = "RETURN", - shift = At.Shift.BEFORE - ) - ) - private void moreculling$onBake(Function textureGetter, ModelState settings, - boolean hasDepth, CallbackInfoReturnable cir) { - BakedModel bakedModel = cir.getReturnValue(); - if (bakedModel == null) { - return; - } - BakedOpacity bakedOpacity = (BakedOpacity) bakedModel; - if (!bakedOpacity.moreculling$canSetCullingShape()) { - return; - } - ResourceLocation id = parent.parentLocation; - if (moreculling$getUseModelShape(id) && settings.getRotation() == Transformation.identity()) { - List modelElementList = this.getElements(); - if (modelElementList != null && !modelElementList.isEmpty()) { - VoxelShape voxelShape = Shapes.empty(); - for (BlockElement e : modelElementList) { - if (e.rotation == null || e.rotation.angle() == 0) { - VoxelShape shape = Block.box( - e.from.x, e.from.y, e.from.z, e.to.x, e.to.y, e.to.z - ); - voxelShape = Shapes.or(voxelShape, shape); - } - } - bakedOpacity.moreculling$setCullingShape(voxelShape); - return; - } - } else { - List cullShapeElementList = moreculling$getCullShapeElements(id); - if (cullShapeElementList != null && !cullShapeElementList.isEmpty()) { - VoxelShape voxelShape = Shapes.empty(); - for (CullShapeElement e : cullShapeElementList) { - VoxelShape shape = Block.box(e.from.x, e.from.y, e.from.z, e.to.x, e.to.y, e.to.z); - voxelShape = Shapes.or(voxelShape, shape); - } - bakedOpacity.moreculling$setCullingShape(voxelShape); - return; - } - } - bakedOpacity.moreculling$setCullingShape(null); - } + }*/ } diff --git a/common/src/main/java/ca/fxco/moreculling/mixin/renderers/ItemRenderer_apiMixin.java b/common/src/main/java/ca/fxco/moreculling/mixin/renderers/ItemRenderer_apiMixin.java deleted file mode 100644 index 28256db8..00000000 --- a/common/src/main/java/ca/fxco/moreculling/mixin/renderers/ItemRenderer_apiMixin.java +++ /dev/null @@ -1,69 +0,0 @@ -package ca.fxco.moreculling.mixin.renderers; - -import ca.fxco.moreculling.api.renderers.ExtendedItemRenderer; -import ca.fxco.moreculling.states.ItemRendererStates; -import ca.fxco.moreculling.utils.DirectionUtils; -import com.mojang.blaze3d.vertex.PoseStack; -import com.mojang.blaze3d.vertex.VertexConsumer; -import net.minecraft.client.Camera; -import net.minecraft.client.renderer.MultiBufferSource; -import net.minecraft.client.renderer.entity.ItemRenderer; -import net.minecraft.client.renderer.entity.state.ItemFrameRenderState; -import net.minecraft.client.renderer.texture.OverlayTexture; -import net.minecraft.client.resources.model.BakedModel; -import net.minecraft.core.Direction; -import net.minecraft.world.item.ItemDisplayContext; -import net.minecraft.world.item.ItemStack; -import org.jetbrains.annotations.Nullable; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -@Mixin(ItemRenderer.class) -public abstract class ItemRenderer_apiMixin implements ExtendedItemRenderer { - - @Shadow protected abstract void renderModelLists(BakedModel model, ItemStack stack, int light, - int overlay, PoseStack poseStack, VertexConsumer vertices); - - @Shadow public abstract void render(ItemStack itemStack, ItemDisplayContext displayContext, boolean leftHand, - PoseStack poseStack, MultiBufferSource bufferSource, int combinedLight, - int combinedOverlay, BakedModel model); - - @Override - public void moreculling$renderBakedItemModelWithoutFace(BakedModel model, ItemStack stack, int light, int overlay, - PoseStack pose, VertexConsumer vertices, - @Nullable Direction withoutFace) { - ItemRendererStates.DIRECTIONS = DirectionUtils.getAllDirectionsExcluding(withoutFace); - this.renderModelLists(model, stack, light, overlay, pose, vertices); - ItemRendererStates.DIRECTIONS = null; - } - - @Override - public void moreculling$renderBakedItemModelOnly3Faces(BakedModel model, ItemStack stack, int light, int overlay, - PoseStack pose, VertexConsumer vertices, - Direction faceX, Direction faceY, Direction faceZ) { - ItemRendererStates.DIRECTIONS = new Direction[] { faceX, faceY, faceZ }; - this.renderModelLists(model, stack, light, overlay, pose, vertices); - ItemRendererStates.DIRECTIONS = null; - } - - @Override - public void moreculling$renderBakedItemModelForFace(BakedModel model, ItemStack stack, int light, int overlay, - PoseStack pose, VertexConsumer vertices, - Direction face) { - ItemRendererStates.DIRECTIONS = new Direction[] { face }; - this.renderModelLists(model, stack, light, overlay, pose, vertices); - ItemRendererStates.DIRECTIONS = null; - } - - @Override - public void moreculling$renderItemFrameItem(ItemStack stack, PoseStack pose, - MultiBufferSource multiBufferSource, - int light, ItemFrameRenderState frame, Camera camera) { - ItemRendererStates.ITEM_FRAME = frame; - ItemRendererStates.CAMERA = camera; - this.render(stack, ItemDisplayContext.FIXED, false, pose, - multiBufferSource, light, OverlayTexture.NO_OVERLAY, frame.itemModel); - ItemRendererStates.ITEM_FRAME = null; - ItemRendererStates.CAMERA = null; - } -} diff --git a/common/src/main/java/ca/fxco/moreculling/mixin/renderers/ItemRenderer_faceCullingMixin.java b/common/src/main/java/ca/fxco/moreculling/mixin/renderers/ItemRenderer_faceCullingMixin.java index 369c8027..ebde55cb 100644 --- a/common/src/main/java/ca/fxco/moreculling/mixin/renderers/ItemRenderer_faceCullingMixin.java +++ b/common/src/main/java/ca/fxco/moreculling/mixin/renderers/ItemRenderer_faceCullingMixin.java @@ -1,23 +1,41 @@ package ca.fxco.moreculling.mixin.renderers; +import ca.fxco.moreculling.MoreCulling; +import ca.fxco.moreculling.api.model.BakedOpacity; import ca.fxco.moreculling.states.ItemRendererStates; +import ca.fxco.moreculling.utils.CullingUtils; import ca.fxco.moreculling.utils.DirectionUtils; +import ca.fxco.moreculling.utils.TransformationUtils; import com.llamalad7.mixinextras.injector.wrapoperation.Operation; import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import com.mojang.blaze3d.vertex.PoseStack; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.block.model.BakedQuad; +import net.minecraft.client.renderer.block.model.ItemTransform; import net.minecraft.client.renderer.entity.ItemRenderer; +import net.minecraft.client.renderer.entity.state.ItemFrameRenderState; +import net.minecraft.client.renderer.item.ItemStackRenderState; import net.minecraft.client.resources.model.BakedModel; import net.minecraft.core.Direction; import net.minecraft.util.RandomSource; +import net.minecraft.world.item.ItemDisplayContext; import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.phys.Vec3; 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.Redirect; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import java.util.ArrayList; import java.util.Iterator; import java.util.List; +import static ca.fxco.moreculling.utils.DirectionUtils.shiftDirection; +import static net.minecraft.core.Direction.NORTH; +import static net.minecraft.core.Direction.SOUTH; + @Mixin(value = ItemRenderer.class, priority = 1100) public class ItemRenderer_faceCullingMixin { @@ -28,7 +46,7 @@ public class ItemRenderer_faceCullingMixin { target = "Lnet/minecraft/core/Direction;values()[Lnet/minecraft/core/Direction;" ) ) - private Direction[] moreculling$modifyDirections() { + private static Direction[] moreculling$modifyDirections() { return ItemRendererStates.DIRECTIONS == null ? DirectionUtils.DIRECTIONS : ItemRendererStates.DIRECTIONS; } @@ -41,9 +59,9 @@ public class ItemRenderer_faceCullingMixin { "Lnet/minecraft/core/Direction;Lnet/minecraft/util/RandomSource;)Ljava/util/List;" ) ) - private List moreculling$onlySomeFaces$Vanilla(BakedModel instance, BlockState blockState, - Direction direction, RandomSource random, - Operation> original) { + private static List moreculling$onlySomeFaces$Vanilla(BakedModel instance, BlockState blockState, + Direction direction, RandomSource random, + Operation> original) { if (ItemRendererStates.DIRECTIONS != null) { List bakedQuads = new ArrayList<>(original.call(instance, blockState, direction, random)); Iterator iterator = bakedQuads.iterator(); @@ -61,4 +79,70 @@ public class ItemRenderer_faceCullingMixin { } return original.call(instance, blockState, direction, random); } + + @Inject( + method = "renderItem", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/client/renderer/entity/ItemRenderer;renderModelLists(" + + "Lnet/minecraft/client/resources/model/BakedModel;" + + "[IIILcom/mojang/blaze3d/vertex/PoseStack;Lcom/mojang/blaze3d/vertex/VertexConsumer;)V" + ) + ) + private static void moreculling$faceRemoval(ItemDisplayContext itemDisplayContext, PoseStack poseStack, + MultiBufferSource multiBufferSource, int light, int overlay, + int[] tintLayers, BakedModel bakedModel, RenderType renderType, + ItemStackRenderState.FoilType foilType, CallbackInfo ci) { + ItemFrameRenderState frame = ItemRendererStates.ITEM_FRAME; + if (frame == null) { + ItemRendererStates.DIRECTIONS = null; + return; + } + Vec3 cameraPos = ItemRendererStates.CAMERA.getPosition(); + Vec3 framePos = new Vec3(frame.x, frame.y, frame.z); + boolean isBlockItem = !((BakedOpacity) bakedModel).moreculling$isItem(); + ItemTransform transformation = ItemRendererStates.TRANSFORMS; + boolean canCull = ((!isBlockItem && !frame.isInvisible) || CullingUtils.shouldCullBack(frame)) && + TransformationUtils.canCullTransformation(transformation); + double dist = ItemRendererStates.CAMERA.getPosition().distanceTo(framePos); + // Make blocks use LOD - If more than range, only render the front and maybe back if it can't cull + if (isBlockItem && dist <= 3) { // 3 Blocks away + ItemRendererStates.DIRECTIONS = null; + } else if (MoreCulling.CONFIG.useItemFrameLOD && !isBlockItem && dist > MoreCulling.CONFIG.itemFrameLODRange) { + if (!canCull) { + ItemRendererStates.DIRECTIONS = new Direction[] { SOUTH, NORTH }; + } else { + ItemRendererStates.DIRECTIONS = new Direction[] { SOUTH }; + } + } else { + // EXPERIMENTAL CULLING + // Use smart culling to render only 3 face directions. + // TODO: Add model rotation logic (items need this!) Currently we only support blocks and some models + if (MoreCulling.CONFIG.useItemFrame3FaceCulling && + dist > MoreCulling.CONFIG.itemFrame3FaceCullingRange && + frame.rotation % 2 == 0 && + transformation.rotation.y() == 0 && + transformation.rotation.x() == 0 && + transformation.rotation.z() == 0 + ) { + int rotation = frame.rotation * 45; + Direction facing = frame.direction; + Direction dirX = shiftDirection(facing, + cameraPos.x > framePos.x ? Direction.EAST : Direction.WEST, rotation); + Direction dirY = shiftDirection(facing, + cameraPos.y > framePos.y ? Direction.UP : Direction.DOWN, rotation); + Direction dirZ = shiftDirection(facing, + cameraPos.z > framePos.z ? SOUTH : NORTH, rotation); + ItemRendererStates.DIRECTIONS = new Direction[] { dirX, dirY, dirZ }; + } else { + if (canCull) { + ItemRendererStates.DIRECTIONS = DirectionUtils.getAllDirectionsExcluding( + DirectionUtils.changeDirectionUsingTransformation(NORTH, transformation) + ); + } else { + ItemRendererStates.DIRECTIONS = null; + } + } + } + } } diff --git a/common/src/main/java/ca/fxco/moreculling/mixin/renderers/ItemStackRenderState_apiMixin.java b/common/src/main/java/ca/fxco/moreculling/mixin/renderers/ItemStackRenderState_apiMixin.java new file mode 100644 index 00000000..43cff0b4 --- /dev/null +++ b/common/src/main/java/ca/fxco/moreculling/mixin/renderers/ItemStackRenderState_apiMixin.java @@ -0,0 +1,27 @@ +package ca.fxco.moreculling.mixin.renderers; + +import ca.fxco.moreculling.api.renderers.ExtendedItemStackRenderState; +import ca.fxco.moreculling.states.ItemRendererStates; +import com.mojang.blaze3d.vertex.PoseStack; +import net.minecraft.client.Camera; +import net.minecraft.client.renderer.MultiBufferSource; +import net.minecraft.client.renderer.entity.state.ItemFrameRenderState; +import net.minecraft.client.renderer.item.ItemStackRenderState; +import net.minecraft.client.renderer.texture.OverlayTexture; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +@Mixin(ItemStackRenderState.class) +public abstract class ItemStackRenderState_apiMixin implements ExtendedItemStackRenderState { + @Shadow public abstract void render(PoseStack p_388193_, MultiBufferSource p_388719_, int p_386913_, int p_387272_); + + @Override + public void moreculling$renderItemFrameItem(PoseStack pose, MultiBufferSource multiBufferSource, + int light, ItemFrameRenderState frame, Camera camera) { + ItemRendererStates.ITEM_FRAME = frame; + ItemRendererStates.CAMERA = camera; + this.render(pose, multiBufferSource, light, OverlayTexture.NO_OVERLAY); + ItemRendererStates.ITEM_FRAME = null; + ItemRendererStates.CAMERA = null; + } +} diff --git a/common/src/main/java/ca/fxco/moreculling/mixin/renderers/ItemStackRenderState_faceCullingMixin.java b/common/src/main/java/ca/fxco/moreculling/mixin/renderers/ItemStackRenderState_faceCullingMixin.java new file mode 100644 index 00000000..3c73dbaa --- /dev/null +++ b/common/src/main/java/ca/fxco/moreculling/mixin/renderers/ItemStackRenderState_faceCullingMixin.java @@ -0,0 +1,31 @@ +package ca.fxco.moreculling.mixin.renderers; + +import ca.fxco.moreculling.states.ItemRendererStates; +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import net.minecraft.client.renderer.block.model.ItemTransform; +import net.minecraft.client.renderer.item.ItemStackRenderState; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +@Mixin(value = ItemStackRenderState.LayerRenderState.class, priority = 1100) +public class ItemStackRenderState_faceCullingMixin { + + @WrapOperation( + method = "render", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/client/renderer/item/ItemStackRenderState$LayerRenderState;" + + "transform()Lnet/minecraft/client/renderer/block/model/ItemTransform;" + ) + ) + private ItemTransform moreculling$getTransformation( + ItemStackRenderState.LayerRenderState instance, Operation original + ) { + ItemTransform transformation = original.call(instance); + if (ItemRendererStates.ITEM_FRAME != null) { + ItemRendererStates.TRANSFORMS = transformation; + } + return transformation; + } +} diff --git a/common/src/main/java/ca/fxco/moreculling/mixin/renderers/LayerRenderState_apiMixin.java b/common/src/main/java/ca/fxco/moreculling/mixin/renderers/LayerRenderState_apiMixin.java new file mode 100644 index 00000000..e4c63a53 --- /dev/null +++ b/common/src/main/java/ca/fxco/moreculling/mixin/renderers/LayerRenderState_apiMixin.java @@ -0,0 +1,46 @@ +package ca.fxco.moreculling.mixin.renderers; + +import ca.fxco.moreculling.api.renderers.ExtendedItemStackRenderState; +import ca.fxco.moreculling.states.ItemRendererStates; +import ca.fxco.moreculling.utils.DirectionUtils; +import com.mojang.blaze3d.vertex.PoseStack; +import com.mojang.blaze3d.vertex.VertexConsumer; +import net.minecraft.client.renderer.entity.ItemRenderer; +import net.minecraft.client.renderer.item.ItemStackRenderState; +import net.minecraft.client.resources.model.BakedModel; +import net.minecraft.core.Direction; +import org.jetbrains.annotations.Nullable; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +@Mixin(ItemStackRenderState.LayerRenderState.class) +public abstract class LayerRenderState_apiMixin implements ExtendedItemStackRenderState { + @Shadow private int[] tintLayers; + + @Override + public void moreculling$renderBakedItemModelWithoutFace(BakedModel model, int light, int overlay, + PoseStack pose, VertexConsumer vertices, + @Nullable Direction withoutFace) { + ItemRendererStates.DIRECTIONS = DirectionUtils.getAllDirectionsExcluding(withoutFace); + ItemRenderer.renderModelLists(model, this.tintLayers, light, overlay, pose, vertices); + ItemRendererStates.DIRECTIONS = null; + } + + @Override + public void moreculling$renderBakedItemModelOnly3Faces(BakedModel model, int light, int overlay, + PoseStack pose, VertexConsumer vertices, + Direction faceX, Direction faceY, Direction faceZ) { + ItemRendererStates.DIRECTIONS = new Direction[] { faceX, faceY, faceZ }; + ItemRenderer.renderModelLists(model, this.tintLayers, light, overlay, pose, vertices); + ItemRendererStates.DIRECTIONS = null; + } + + @Override + public void moreculling$renderBakedItemModelForFace(BakedModel model, int light, int overlay, + PoseStack pose, VertexConsumer vertices, + Direction face) { + ItemRendererStates.DIRECTIONS = new Direction[] { face }; + ItemRenderer.renderModelLists(model, this.tintLayers, light, overlay, pose, vertices); + ItemRendererStates.DIRECTIONS = null; + } +} diff --git a/common/src/main/java/ca/fxco/moreculling/states/ItemRendererStates.java b/common/src/main/java/ca/fxco/moreculling/states/ItemRendererStates.java index a9e0c51d..15347f13 100644 --- a/common/src/main/java/ca/fxco/moreculling/states/ItemRendererStates.java +++ b/common/src/main/java/ca/fxco/moreculling/states/ItemRendererStates.java @@ -1,6 +1,7 @@ package ca.fxco.moreculling.states; import net.minecraft.client.Camera; +import net.minecraft.client.renderer.block.model.ItemTransform; import net.minecraft.client.renderer.entity.state.ItemFrameRenderState; import net.minecraft.core.Direction; import org.jetbrains.annotations.Nullable; @@ -15,4 +16,5 @@ public class ItemRendererStates { public static @Nullable ItemFrameRenderState ITEM_FRAME; public static Camera CAMERA; public static Direction[] DIRECTIONS; + public static @Nullable ItemTransform TRANSFORMS; } diff --git a/common/src/main/java/ca/fxco/moreculling/utils/CullingUtils.java b/common/src/main/java/ca/fxco/moreculling/utils/CullingUtils.java index 680a70fa..c86823ea 100644 --- a/common/src/main/java/ca/fxco/moreculling/utils/CullingUtils.java +++ b/common/src/main/java/ca/fxco/moreculling/utils/CullingUtils.java @@ -2,6 +2,7 @@ import ca.fxco.moreculling.MoreCulling; import ca.fxco.moreculling.api.blockstate.MoreStateCulling; +import com.mojang.logging.LogUtils; import it.unimi.dsi.fastutil.objects.Object2ByteLinkedOpenHashMap; import net.caffeinemc.mods.sodium.client.SodiumClientMod; import net.minecraft.client.GraphicsStatus; @@ -161,7 +162,7 @@ public static Optional shouldDrawFaceRandom(BlockGetter view, BlockStat public static boolean shouldCullBack(ItemFrameRenderState frame) { Direction dir = frame.direction; - BlockPos posBehind = new BlockPos((int) frame.x, (int) frame.y - 1, (int) frame.z) .relative(dir.getOpposite()); + BlockPos posBehind = new BlockPos((int) frame.x, (int) frame.y, (int) frame.z).relative(dir.getOpposite()); BlockState blockState = Minecraft.getInstance().level.getBlockState(posBehind); return blockState.canOcclude() && blockState.isFaceSturdy(Minecraft.getInstance().level, posBehind, dir); } diff --git a/common/src/main/resources/META-INF/accesstransformer.cfg b/common/src/main/resources/META-INF/accesstransformer.cfg index 6cb63f9a..62fb9ff1 100644 --- a/common/src/main/resources/META-INF/accesstransformer.cfg +++ b/common/src/main/resources/META-INF/accesstransformer.cfg @@ -5,6 +5,7 @@ public net.minecraft.client.model.geom.ModelPart$Vertex public net.minecraft.world.level.block.Block$ShapePairKey (Lnet/minecraft/world/phys/shapes/VoxelShape;Lnet/minecraft/world/phys/shapes/VoxelShape;)V public net.minecraft.world.level.block.Block$ShapePairKey public net.minecraft.client.renderer.CloudRenderer$RelativeCameraPos +public net.minecraft.client.renderer.entity.ItemRenderer renderModelLists(Lnet/minecraft/client/resources/model/BakedModel;[IIILcom/mojang/blaze3d/vertex/PoseStack;Lcom/mojang/blaze3d/vertex/VertexConsumer;)V public net.minecraft.world.level.block.state.BlockBehaviour getOcclusionShape(Lnet/minecraft/world/level/block/state/BlockState;)Lnet/minecraft/world/phys/shapes/VoxelShape; public net.minecraft.world.level.block.SkullBlock getOcclusionShape(Lnet/minecraft/world/level/block/state/BlockState;)Lnet/minecraft/world/phys/shapes/VoxelShape; diff --git a/common/src/main/resources/moreculling.accesswidener b/common/src/main/resources/moreculling.accesswidener index d5aae220..bf721600 100644 --- a/common/src/main/resources/moreculling.accesswidener +++ b/common/src/main/resources/moreculling.accesswidener @@ -4,4 +4,5 @@ accessible method net/minecraft/world/level/block/state/BlockBehaviour getOcclus accessible field net/minecraft/client/renderer/block/model/BlockModel parentLocation Lnet/minecraft/resources/ResourceLocation; accessible class net/minecraft/client/renderer/CloudRenderer$RelativeCameraPos accessible class net/minecraft/world/level/block/Block$ShapePairKey -accessible method net/minecraft/world/level/block/Block$ShapePairKey (Lnet/minecraft/world/phys/shapes/VoxelShape;Lnet/minecraft/world/phys/shapes/VoxelShape;)V \ No newline at end of file +accessible method net/minecraft/world/level/block/Block$ShapePairKey (Lnet/minecraft/world/phys/shapes/VoxelShape;Lnet/minecraft/world/phys/shapes/VoxelShape;)V +accessible method net/minecraft/client/renderer/entity/ItemRenderer renderModelLists (Lnet/minecraft/client/resources/model/BakedModel;[IIILcom/mojang/blaze3d/vertex/PoseStack;Lcom/mojang/blaze3d/vertex/VertexConsumer;)V \ No newline at end of file diff --git a/common/src/main/resources/moreculling.mixins.json b/common/src/main/resources/moreculling.mixins.json index e17b875e..ffc85c73 100644 --- a/common/src/main/resources/moreculling.mixins.json +++ b/common/src/main/resources/moreculling.mixins.json @@ -19,6 +19,7 @@ "blockentity.TheEndGatewayRenderer_beamMixin", "blockentity.SignRenderer_textMixin", "blocks.BaseRailBlock_cullAgainstMixin", + "blocks.cullshape.BaseTorchBlock_voxelMixin", "blocks.cullshape.BrewingStandBlock_voxelMixin", "blocks.cullshape.CampfireBlock_voxelMixin", "blocks.cullshape.ChorusFlowerBlock_voxelMixin", @@ -41,14 +42,16 @@ "entities.ItemFrameRenderer_cullMixin", "gui.SodiumOptionsGUIMixin", "models.BakedModel_extendsMixin", + "models.DelegateBakedModel_cullMixin", "models.SimpleBakedModel_cacheMixin", - "models.BuiltInModel_cacheMixin", "models.cullshape.Deserializer_cullShapeMixin", "models.cullshape.BlockModel_cullShapeMixin", "models.cullshape.BlockStateBase_cullShapeMixin", - "renderers.ModelBlockRenderer_cullMixin", - "renderers.ItemRenderer_apiMixin", - "renderers.ItemRenderer_faceCullingMixin" + "renderers.ItemRenderer_faceCullingMixin", + "renderers.ItemStackRenderState_apiMixin", + "renderers.ItemStackRenderState_faceCullingMixin", + "renderers.LayerRenderState_apiMixin", + "renderers.ModelBlockRenderer_cullMixin" ], "injectors": { "defaultRequire": 1 diff --git a/fabric/build.gradle b/fabric/build.gradle index 8e66e4b4..31dd2394 100644 --- a/fabric/build.gradle +++ b/fabric/build.gradle @@ -12,7 +12,7 @@ dependencies { modImplementation "net.fabricmc.fabric-api:fabric-api:${fabric_version}" modImplementation "maven.modrinth:modmenu:${project.modmenu_version}" - modImplementation "maven.modrinth:sodium:${project.sodium_version}-fabric" + modCompileOnly "maven.modrinth:sodium:${project.sodium_version}-fabric" // ^ Change to `modCompileOnly` to test without sodium //modImplementation "maven.modrinth:client-tweaks:${project.clienttweaks_version}+fabric-${project.minecraft_version}" //modImplementation "maven.modrinth:balm:${project.clienttweaks_version}+fabric-${project.minecraft_version}" diff --git a/fabric/src/main/java/ca/fxco/moreculling/mixin/models/ForwardingBakedModel_compatMixin.java b/fabric/src/main/java/ca/fxco/moreculling/mixin/models/ForwardingBakedModel_compatMixin.java deleted file mode 100644 index 6d12891c..00000000 --- a/fabric/src/main/java/ca/fxco/moreculling/mixin/models/ForwardingBakedModel_compatMixin.java +++ /dev/null @@ -1,46 +0,0 @@ -package ca.fxco.moreculling.mixin.models; - -import ca.fxco.moreculling.api.model.BakedOpacity; -import me.fallenbreath.conditionalmixin.api.annotation.Condition; -import me.fallenbreath.conditionalmixin.api.annotation.Restriction; -import net.fabricmc.fabric.api.renderer.v1.model.ForwardingBakedModel; -import net.minecraft.client.resources.model.BakedModel; -import net.minecraft.core.Direction; -import net.minecraft.world.level.block.state.BlockState; -import net.minecraft.world.phys.shapes.VoxelShape; -import org.jetbrains.annotations.Nullable; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; - -@Restriction(require = @Condition("fabric-renderer-api-v1")) -@Mixin(ForwardingBakedModel.class) -public class ForwardingBakedModel_compatMixin implements BakedOpacity { - - @Shadow - protected BakedModel wrapped; - - @Override - public boolean moreculling$hasTextureTranslucency(@Nullable BlockState state, @Nullable Direction direction) { - return ((BakedOpacity) wrapped).moreculling$hasTextureTranslucency(state, direction); - } - - @Override - public void moreculling$resetTranslucencyCache() { - ((BakedOpacity) wrapped).moreculling$resetTranslucencyCache(); - } - - @Override - public @Nullable VoxelShape moreculling$getCullingShape(BlockState state) { - return ((BakedOpacity) wrapped).moreculling$getCullingShape(state); - } - - @Override - public void moreculling$setCullingShape(VoxelShape cullingShape) { - ((BakedOpacity) wrapped).moreculling$setCullingShape(cullingShape); - } - - @Override - public boolean moreculling$canSetCullingShape() { - return ((BakedOpacity) wrapped).moreculling$canSetCullingShape(); - } -} diff --git a/fabric/src/main/java/ca/fxco/moreculling/mixin/models/ItemModelGenerator_cullMixin.java b/fabric/src/main/java/ca/fxco/moreculling/mixin/models/ItemModelGenerator_cullMixin.java new file mode 100644 index 00000000..31a575df --- /dev/null +++ b/fabric/src/main/java/ca/fxco/moreculling/mixin/models/ItemModelGenerator_cullMixin.java @@ -0,0 +1,31 @@ +package ca.fxco.moreculling.mixin.models; + +import ca.fxco.moreculling.api.model.BakedOpacity; +import net.minecraft.client.renderer.block.model.ItemModelGenerator; +import net.minecraft.client.renderer.block.model.ItemTransforms; +import net.minecraft.client.renderer.block.model.TextureSlots; +import net.minecraft.client.resources.model.BakedModel; +import net.minecraft.client.resources.model.ModelState; +import net.minecraft.client.resources.model.SpriteGetter; +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; + +@Mixin(ItemModelGenerator.class) +public class ItemModelGenerator_cullMixin { + @Inject( + method = "bake(Lnet/minecraft/client/renderer/block/model/TextureSlots;" + + "Lnet/minecraft/client/resources/model/SpriteGetter;" + + "Lnet/minecraft/client/resources/model/ModelState;" + + "ZZLnet/minecraft/client/renderer/block/model/ItemTransforms;" + + ")Lnet/minecraft/client/resources/model/BakedModel;", + at = @At( + value = "RETURN" + ) + ) + private void markAsItem(TextureSlots p_387202_, SpriteGetter p_387257_, ModelState p_387172_, boolean p_388328_, + boolean p_387288_, ItemTransforms p_388238_, CallbackInfoReturnable cir) { + ((BakedOpacity) cir.getReturnValue()).moreculling$setIsItem(); + } +} diff --git a/fabric/src/main/java/ca/fxco/moreculling/mixin/models/cullshape/BlockModel_fabricCullShapeMixin.java b/fabric/src/main/java/ca/fxco/moreculling/mixin/models/cullshape/BlockModel_fabricCullShapeMixin.java new file mode 100644 index 00000000..b31aafe2 --- /dev/null +++ b/fabric/src/main/java/ca/fxco/moreculling/mixin/models/cullshape/BlockModel_fabricCullShapeMixin.java @@ -0,0 +1,85 @@ +package ca.fxco.moreculling.mixin.models.cullshape; + +import ca.fxco.moreculling.api.model.BakedOpacity; +import ca.fxco.moreculling.api.model.CullShapeElement; +import ca.fxco.moreculling.api.model.ExtendedUnbakedModel; +import com.mojang.math.Transformation; +import net.minecraft.client.renderer.block.model.BlockElement; +import net.minecraft.client.renderer.block.model.BlockModel; +import net.minecraft.client.renderer.block.model.ItemTransforms; +import net.minecraft.client.renderer.block.model.TextureSlots; +import net.minecraft.client.resources.model.BakedModel; +import net.minecraft.client.resources.model.ModelBaker; +import net.minecraft.client.resources.model.ModelState; +import net.minecraft.client.resources.model.UnbakedModel; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.phys.shapes.Shapes; +import net.minecraft.world.phys.shapes.VoxelShape; +import org.jetbrains.annotations.Nullable; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import java.util.List; + +@Mixin(BlockModel.class) +public abstract class BlockModel_fabricCullShapeMixin implements ExtendedUnbakedModel { + + @Shadow + @Nullable + private UnbakedModel parent; + + @Shadow @Nullable abstract List getElements(); + + @Inject( + method = "bake", + at = @At( + value = "RETURN", + shift = At.Shift.BEFORE + ) + ) + private void moreculling$onBake(TextureSlots p_387258_, ModelBaker p_388168_, ModelState settings, + boolean p_111455_, boolean p_387632_, ItemTransforms p_386577_, + CallbackInfoReturnable cir) { + BakedModel bakedModel = cir.getReturnValue(); + if (bakedModel == null || !(parent instanceof BlockModel blockModel)) { + return; + } + BakedOpacity bakedOpacity = (BakedOpacity) bakedModel; + if (!bakedOpacity.moreculling$canSetCullingShape()) { + return; + } + ResourceLocation id = blockModel.parentLocation; + if (moreculling$getUseModelShape(id) && settings.getRotation() == Transformation.identity()) { + List modelElementList = this.getElements(); + if (modelElementList != null && !modelElementList.isEmpty()) { + VoxelShape voxelShape = Shapes.empty(); + for (BlockElement e : modelElementList) { + if (e.rotation == null || e.rotation.angle() == 0) { + VoxelShape shape = Block.box( + e.from.x, e.from.y, e.from.z, e.to.x, e.to.y, e.to.z + ); + voxelShape = Shapes.or(voxelShape, shape); + } + } + bakedOpacity.moreculling$setCullingShape(voxelShape); + return; + } + } else { + List cullShapeElementList = moreculling$getCullShapeElements(id); + if (cullShapeElementList != null && !cullShapeElementList.isEmpty()) { + VoxelShape voxelShape = Shapes.empty(); + for (CullShapeElement e : cullShapeElementList) { + VoxelShape shape = Block.box(e.from.x, e.from.y, e.from.z, e.to.x, e.to.y, e.to.z); + voxelShape = Shapes.or(voxelShape, shape); + } + bakedOpacity.moreculling$setCullingShape(voxelShape); + return; + } + } + bakedOpacity.moreculling$setCullingShape(null); + } +} diff --git a/fabric/src/main/java/ca/fxco/moreculling/mixin/renderers/ItemRenderer_fabricFaceCullingMixin.java b/fabric/src/main/java/ca/fxco/moreculling/mixin/renderers/ItemRenderer_fabricFaceCullingMixin.java deleted file mode 100644 index 6aa495e0..00000000 --- a/fabric/src/main/java/ca/fxco/moreculling/mixin/renderers/ItemRenderer_fabricFaceCullingMixin.java +++ /dev/null @@ -1,124 +0,0 @@ -package ca.fxco.moreculling.mixin.renderers; - -import ca.fxco.moreculling.MoreCulling; -import ca.fxco.moreculling.states.ItemRendererStates; -import ca.fxco.moreculling.utils.CullingUtils; -import ca.fxco.moreculling.utils.DirectionUtils; -import ca.fxco.moreculling.utils.TransformationUtils; -import com.llamalad7.mixinextras.injector.wrapoperation.Operation; -import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; -import com.llamalad7.mixinextras.sugar.Share; -import com.llamalad7.mixinextras.sugar.ref.LocalRef; -import com.mojang.blaze3d.vertex.PoseStack; -import net.minecraft.client.renderer.MultiBufferSource; -import net.minecraft.client.renderer.block.model.ItemTransform; -import net.minecraft.client.renderer.block.model.ItemTransforms; -import net.minecraft.client.renderer.entity.ItemRenderer; -import net.minecraft.client.renderer.entity.state.ItemFrameRenderState; -import net.minecraft.client.resources.model.BakedModel; -import net.minecraft.core.Direction; -import net.minecraft.world.item.BlockItem; -import net.minecraft.world.item.ItemDisplayContext; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.phys.Vec3; -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; - -import static ca.fxco.moreculling.utils.DirectionUtils.shiftDirection; -import static net.minecraft.core.Direction.NORTH; -import static net.minecraft.core.Direction.SOUTH; - -@Mixin(value = ItemRenderer.class, priority = 1100) -public class ItemRenderer_fabricFaceCullingMixin { - - @WrapOperation( - method = "renderItemModelRaw", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/client/renderer/block/model/ItemTransforms;getTransform(" + - "Lnet/minecraft/world/item/ItemDisplayContext;)" + - "Lnet/minecraft/client/renderer/block/model/ItemTransform;" - ) - ) - private ItemTransform moreculling$getTransformation( - ItemTransforms modelTransformation, ItemDisplayContext renderMode, - Operation original, @Share("transformation") LocalRef transformationRef - ) { - ItemTransform transformation = original.call(modelTransformation, renderMode); - if (ItemRendererStates.ITEM_FRAME != null) { - transformationRef.set(transformation); - } - return transformation; - } - - @Inject( - method = "renderItem", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/client/renderer/entity/ItemRenderer;renderModelLists(" + - "Lnet/minecraft/client/resources/model/BakedModel;" + - "Lnet/minecraft/world/item/ItemStack;IILcom/mojang/blaze3d/vertex/PoseStack;" + - "Lcom/mojang/blaze3d/vertex/VertexConsumer;)V" - ) - ) - private void moreculling$faceRemoval(ItemStack stack, ItemDisplayContext displayContext, - PoseStack poseStack, MultiBufferSource multiBufferSource, int light, int overlay, - BakedModel model, boolean bl, CallbackInfo ci, - @Share("transformation") LocalRef transformationRef) { - ItemFrameRenderState frame = ItemRendererStates.ITEM_FRAME; - if (frame == null) { - ItemRendererStates.DIRECTIONS = null; - return; - } - Vec3 cameraPos = ItemRendererStates.CAMERA.getPosition(); - Vec3 framePos = new Vec3(frame.x, frame.y, frame.z) ; - boolean isBlockItem = stack.getItem() instanceof BlockItem; - ItemTransform transformation = transformationRef.get(); - if (transformation == null) - return; - boolean canCull = ((!isBlockItem && !frame.isInvisible) || CullingUtils.shouldCullBack(frame)) && - TransformationUtils.canCullTransformation(transformation); - double dist = ItemRendererStates.CAMERA.getPosition().distanceTo(framePos); - // Make blocks use LOD - If more than range, only render the front and maybe back if it can't cull - if (isBlockItem && dist <= 3) { // 3 Blocks away - ItemRendererStates.DIRECTIONS = null; - } else if (MoreCulling.CONFIG.useItemFrameLOD && !isBlockItem && dist > MoreCulling.CONFIG.itemFrameLODRange) { - if (!canCull) { - ItemRendererStates.DIRECTIONS = new Direction[] { SOUTH, NORTH }; - } else { - ItemRendererStates.DIRECTIONS = new Direction[] { SOUTH }; - } - } else { - // EXPERIMENTAL CULLING - // Use smart culling to render only 3 face directions. - // TODO: Add model rotation logic (items need this!) Currently we only support blocks and some models - if (MoreCulling.CONFIG.useItemFrame3FaceCulling && - dist > MoreCulling.CONFIG.itemFrame3FaceCullingRange && - frame.rotation % 2 == 0 && - transformation.rotation.y() == 0 && - transformation.rotation.x() == 0 && - transformation.rotation.z() == 0 - ) { - int rotation = frame.rotation * 45; - Direction facing = frame.direction; - Direction dirX = shiftDirection(facing, - cameraPos.x > framePos.x ? Direction.EAST : Direction.WEST, rotation); - Direction dirY = shiftDirection(facing, - cameraPos.y > framePos.y ? Direction.UP : Direction.DOWN, rotation); - Direction dirZ = shiftDirection(facing, - cameraPos.z > framePos.z ? SOUTH : NORTH, rotation); - ItemRendererStates.DIRECTIONS = new Direction[] { dirX, dirY, dirZ }; - } else { - if (canCull) { - ItemRendererStates.DIRECTIONS = DirectionUtils.getAllDirectionsExcluding( - DirectionUtils.changeDirectionUsingTransformation(NORTH, transformation) - ); - } else { - ItemRendererStates.DIRECTIONS = null; - } - } - } - } -} diff --git a/fabric/src/main/resources/moreculling.fabric.mixins.json b/fabric/src/main/resources/moreculling.fabric.mixins.json index e3b1a1fb..690ae7bc 100644 --- a/fabric/src/main/resources/moreculling.fabric.mixins.json +++ b/fabric/src/main/resources/moreculling.fabric.mixins.json @@ -7,11 +7,11 @@ "plugin": "ca.fxco.moreculling.config.MixinConfigPlugin", "client": [ "blockstates.Block_fabricDrawSideMixin", - "models.ForwardingBakedModel_compatMixin", + "models.ItemModelGenerator_cullMixin", "models.MultiPartBakedModel_cacheMixin", "models.SimpleBakedModel_fabricCacheMixin", "models.WeightedBakedModel_cacheMixin", - "renderers.ItemRenderer_fabricFaceCullingMixin" + "models.cullshape.BlockModel_fabricCullShapeMixin" ], "injectors": { "defaultRequire": 1 diff --git a/gradle.properties b/gradle.properties index 42479407..aa359a1e 100755 --- a/gradle.properties +++ b/gradle.properties @@ -5,23 +5,24 @@ org.gradle.caching=true org.gradle.configuration-cache=true # Minecraft version -minecraft_version=1.21.3 +minecraft_version=1.21.4 minecraft_version_range=[1.21.2,) -neo_form_version=1.21.3-20241023.131943 +#https://projects.neoforged.net/neoforged/neoform +neo_form_version=1.21.4-20241203.161809 # Parchment parchment_minecraft=1.21 parchment_version=2024.07.28 # NeoForge -neoforge_version=21.3.0-beta +neoforge_version=21.4.0-beta neoforge_loader_version_range=[21.0.0-beta,) # Fabric version -fabric_loader_version=0.16.4 +fabric_loader_version=0.16.9 # Mod Properties -mod_version=1.1.0 +mod_version=1.2.0-beta.1 maven_group=ca.fxco.moreculling archives_base_name=moreculling license=GPL-3.0-only @@ -34,7 +35,7 @@ java_version=21 modmenu_version=12.0.0-beta.1 # Fabric Compatibility -fabric_version=0.106.1+1.21.3 +fabric_version=0.110.5+1.21.4 # Sodium Compatibility sodium_version=mc1.21.3-0.6.0-beta.4 diff --git a/neoforge/build.gradle b/neoforge/build.gradle index 66d66b8c..f7c42c74 100644 --- a/neoforge/build.gradle +++ b/neoforge/build.gradle @@ -23,9 +23,6 @@ neoForge { client { client() } - data { - data() - } server { server() } @@ -38,7 +35,7 @@ neoForge { } dependencies { - implementation "maven.modrinth:sodium:${project.sodium_version}-neoforge" + compileOnly "maven.modrinth:sodium:${project.sodium_version}-neoforge" runtimeOnly "me.shedaniel.cloth:cloth-config-neoforge:${project.cloth_config_version}" //implementation "maven.modrinth:client-tweaks:${project.clienttweaks_version}+neoforge-${project.minecraft_version}" diff --git a/neoforge/src/main/java/ca/fxco/moreculling/mixin/models/ItemModelGenerator_cullMixin.java b/neoforge/src/main/java/ca/fxco/moreculling/mixin/models/ItemModelGenerator_cullMixin.java new file mode 100644 index 00000000..19b99ae1 --- /dev/null +++ b/neoforge/src/main/java/ca/fxco/moreculling/mixin/models/ItemModelGenerator_cullMixin.java @@ -0,0 +1,29 @@ +package ca.fxco.moreculling.mixin.models; + +import ca.fxco.moreculling.api.model.BakedOpacity; +import net.minecraft.client.renderer.block.model.ItemModelGenerator; +import net.minecraft.client.renderer.block.model.ItemTransforms; +import net.minecraft.client.renderer.block.model.TextureSlots; +import net.minecraft.client.resources.model.BakedModel; +import net.minecraft.client.resources.model.ModelState; +import net.minecraft.client.resources.model.SpriteGetter; +import net.neoforged.neoforge.client.RenderTypeGroup; +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; + +@Mixin(ItemModelGenerator.class) +public class ItemModelGenerator_cullMixin { + @Inject( + method = "bake(Lnet/minecraft/client/renderer/block/model/TextureSlots;Lnet/minecraft/client/resources/model/SpriteGetter;Lnet/minecraft/client/resources/model/ModelState;ZZLnet/minecraft/client/renderer/block/model/ItemTransforms;Lnet/neoforged/neoforge/client/RenderTypeGroup;)Lnet/minecraft/client/resources/model/BakedModel;", + at = @At( + value = "RETURN" + ) + ) + private void markAsItem(TextureSlots p_387202_, SpriteGetter p_387257_, ModelState p_387172_, + boolean p_388328_, boolean p_387288_, ItemTransforms p_388238_, + RenderTypeGroup renderTypes, CallbackInfoReturnable cir) { + ((BakedOpacity) cir.getReturnValue()).moreculling$setIsItem(); + } +} diff --git a/neoforge/src/main/java/ca/fxco/moreculling/mixin/models/cullshape/BlockModel_neoforgeCullShapeMixin.java b/neoforge/src/main/java/ca/fxco/moreculling/mixin/models/cullshape/BlockModel_neoforgeCullShapeMixin.java new file mode 100644 index 00000000..3ac05adb --- /dev/null +++ b/neoforge/src/main/java/ca/fxco/moreculling/mixin/models/cullshape/BlockModel_neoforgeCullShapeMixin.java @@ -0,0 +1,87 @@ +package ca.fxco.moreculling.mixin.models.cullshape; + +import ca.fxco.moreculling.api.model.BakedOpacity; +import ca.fxco.moreculling.api.model.CullShapeElement; +import ca.fxco.moreculling.api.model.ExtendedUnbakedModel; +import com.mojang.math.Transformation; +import net.minecraft.client.renderer.block.model.BlockElement; +import net.minecraft.client.renderer.block.model.BlockModel; +import net.minecraft.client.renderer.block.model.ItemTransforms; +import net.minecraft.client.renderer.block.model.TextureSlots; +import net.minecraft.client.resources.model.BakedModel; +import net.minecraft.client.resources.model.ModelBaker; +import net.minecraft.client.resources.model.ModelState; +import net.minecraft.client.resources.model.UnbakedModel; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.util.context.ContextMap; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.phys.shapes.Shapes; +import net.minecraft.world.phys.shapes.VoxelShape; +import org.jetbrains.annotations.Nullable; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import java.util.List; + +@Mixin(BlockModel.class) +public abstract class BlockModel_neoforgeCullShapeMixin implements ExtendedUnbakedModel { + + @Shadow + @Nullable + private UnbakedModel parent; + + @Shadow @Nullable abstract List getElements(); + + @Inject( + method = "bake", + at = @At( + value = "RETURN", + shift = At.Shift.BEFORE + ) + ) + private void moreculling$onBake(TextureSlots p_387258_, ModelBaker p_388168_, ModelState settings, + boolean p_111455_, boolean p_387632_, ItemTransforms p_386577_, + ContextMap additionalProperties, + CallbackInfoReturnable cir) { + BakedModel bakedModel = cir.getReturnValue(); + if (bakedModel == null || !(parent instanceof BlockModel blockModel)) { + return; + } + BakedOpacity bakedOpacity = (BakedOpacity) bakedModel; + if (!bakedOpacity.moreculling$canSetCullingShape()) { + return; + } + ResourceLocation id = blockModel.parentLocation; + if (moreculling$getUseModelShape(id) && settings.getRotation() == Transformation.identity()) { + List modelElementList = this.getElements(); + if (modelElementList != null && !modelElementList.isEmpty()) { + VoxelShape voxelShape = Shapes.empty(); + for (BlockElement e : modelElementList) { + if (e.rotation == null || e.rotation.angle() == 0) { + VoxelShape shape = Block.box( + e.from.x, e.from.y, e.from.z, e.to.x, e.to.y, e.to.z + ); + voxelShape = Shapes.or(voxelShape, shape); + } + } + bakedOpacity.moreculling$setCullingShape(voxelShape); + return; + } + } else { + List cullShapeElementList = moreculling$getCullShapeElements(id); + if (cullShapeElementList != null && !cullShapeElementList.isEmpty()) { + VoxelShape voxelShape = Shapes.empty(); + for (CullShapeElement e : cullShapeElementList) { + VoxelShape shape = Block.box(e.from.x, e.from.y, e.from.z, e.to.x, e.to.y, e.to.z); + voxelShape = Shapes.or(voxelShape, shape); + } + bakedOpacity.moreculling$setCullingShape(voxelShape); + return; + } + } + bakedOpacity.moreculling$setCullingShape(null); + } +} diff --git a/neoforge/src/main/java/ca/fxco/moreculling/mixin/renderers/IBakedModelExtension_faceCullingMixin.java b/neoforge/src/main/java/ca/fxco/moreculling/mixin/renderers/IBakedModelExtension_faceCullingMixin.java new file mode 100644 index 00000000..1f688b54 --- /dev/null +++ b/neoforge/src/main/java/ca/fxco/moreculling/mixin/renderers/IBakedModelExtension_faceCullingMixin.java @@ -0,0 +1,35 @@ +package ca.fxco.moreculling.mixin.renderers; + +import ca.fxco.moreculling.states.ItemRendererStates; +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import net.minecraft.client.renderer.block.model.ItemTransform; +import net.minecraft.client.renderer.block.model.ItemTransforms; +import net.minecraft.world.item.ItemDisplayContext; +import net.neoforged.neoforge.client.extensions.IBakedModelExtension; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +@Mixin(value = IBakedModelExtension.class, priority = 1100) +public interface IBakedModelExtension_faceCullingMixin { + + @WrapOperation( + method = "applyTransform", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/client/renderer/block/model/ItemTransforms;getTransform(" + + "Lnet/minecraft/world/item/ItemDisplayContext;)" + + "Lnet/minecraft/client/renderer/block/model/ItemTransform;" + ) + ) + private ItemTransform moreculling$getTransformation( + ItemTransforms instance, ItemDisplayContext displayContext, + Operation original + ) { + ItemTransform transformation = original.call(instance, displayContext); + if (ItemRendererStates.ITEM_FRAME != null) { + ItemRendererStates.TRANSFORMS = transformation; + } + return transformation; + } +} diff --git a/neoforge/src/main/java/ca/fxco/moreculling/mixin/renderers/ItemRenderer_neoforgeFaceCullingMixin.java b/neoforge/src/main/java/ca/fxco/moreculling/mixin/renderers/ItemRenderer_neoforgeFaceCullingMixin.java deleted file mode 100644 index 7a92510a..00000000 --- a/neoforge/src/main/java/ca/fxco/moreculling/mixin/renderers/ItemRenderer_neoforgeFaceCullingMixin.java +++ /dev/null @@ -1,125 +0,0 @@ -package ca.fxco.moreculling.mixin.renderers; - -import ca.fxco.moreculling.MoreCulling; -import ca.fxco.moreculling.states.ItemRendererStates; -import ca.fxco.moreculling.utils.CullingUtils; -import ca.fxco.moreculling.utils.DirectionUtils; -import ca.fxco.moreculling.utils.TransformationUtils; -import com.llamalad7.mixinextras.injector.wrapoperation.Operation; -import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; -import com.llamalad7.mixinextras.sugar.Share; -import com.llamalad7.mixinextras.sugar.ref.LocalRef; -import com.mojang.blaze3d.vertex.PoseStack; -import net.minecraft.client.renderer.MultiBufferSource; -import net.minecraft.client.renderer.block.model.ItemTransform; -import net.minecraft.client.renderer.entity.ItemRenderer; -import net.minecraft.client.renderer.entity.state.ItemFrameRenderState; -import net.minecraft.client.resources.model.BakedModel; -import net.minecraft.core.Direction; -import net.minecraft.world.item.BlockItem; -import net.minecraft.world.item.ItemDisplayContext; -import net.minecraft.world.item.ItemStack; -import net.minecraft.world.phys.Vec3; -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; - -import static ca.fxco.moreculling.utils.DirectionUtils.shiftDirection; -import static net.minecraft.core.Direction.NORTH; -import static net.minecraft.core.Direction.SOUTH; - -@Mixin(value = ItemRenderer.class, priority = 1100) -public class ItemRenderer_neoforgeFaceCullingMixin { - - @WrapOperation( - method = "renderItemModelRaw", - at = @At( - value = "INVOKE", - target = "Lnet/neoforged/neoforge/client/ClientHooks;handleCameraTransforms(" + - "Lcom/mojang/blaze3d/vertex/PoseStack;" + - "Lnet/minecraft/client/resources/model/BakedModel;" + - "Lnet/minecraft/world/item/ItemDisplayContext" + - ";Z)Lnet/minecraft/client/resources/model/BakedModel;" - ) - ) - private BakedModel moreculling$getTransformation( - PoseStack poseStack, BakedModel model, ItemDisplayContext displayContext, boolean applyLeftHandTransform, - Operation original, @Share("transformation") LocalRef transformationRef - ) { - ItemTransform transformation = model.getTransforms().getTransform(displayContext); - if (ItemRendererStates.ITEM_FRAME != null) { - transformationRef.set(transformation); - } - return original.call(poseStack, model, displayContext, applyLeftHandTransform); - } - - @Inject( - method = "renderItem", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/client/renderer/entity/ItemRenderer;renderModelLists(" + - "Lnet/minecraft/client/resources/model/BakedModel;" + - "Lnet/minecraft/world/item/ItemStack;IILcom/mojang/blaze3d/vertex/PoseStack;" + - "Lcom/mojang/blaze3d/vertex/VertexConsumer;)V" - ) - ) - private void moreculling$faceRemoval(ItemStack stack, ItemDisplayContext p_361627_, PoseStack p_360423_, - MultiBufferSource p_360415_, int p_361265_, int p_364771_, - BakedModel p_363970_, boolean p_364829_, CallbackInfo ci, - @Share("transformation") LocalRef transformationRef) { - ItemFrameRenderState frame = ItemRendererStates.ITEM_FRAME; - if (frame == null) { - ItemRendererStates.DIRECTIONS = null; - return; - } - Vec3 cameraPos = ItemRendererStates.CAMERA.getPosition(); - Vec3 framePos = new Vec3(frame.x, frame.y, frame.z) ; - boolean isBlockItem = stack.getItem() instanceof BlockItem; - ItemTransform transformation = transformationRef.get(); - if (transformation == null) - return; - boolean canCull = ((!isBlockItem && !frame.isInvisible) || CullingUtils.shouldCullBack(frame)) && - TransformationUtils.canCullTransformation(transformation); - double dist = ItemRendererStates.CAMERA.getPosition().distanceTo(framePos); - // Make blocks use LOD - If more than range, only render the front and maybe back if it can't cull - if (isBlockItem && dist <= 3) { // 3 Blocks away - ItemRendererStates.DIRECTIONS = null; - } else if (MoreCulling.CONFIG.useItemFrameLOD && !isBlockItem && dist > MoreCulling.CONFIG.itemFrameLODRange) { - if (!canCull) { - ItemRendererStates.DIRECTIONS = new Direction[] { SOUTH, NORTH }; - } else { - ItemRendererStates.DIRECTIONS = new Direction[] { SOUTH }; - } - } else { - // EXPERIMENTAL CULLING - // Use smart culling to render only 3 face directions. - // TODO: Add model rotation logic (items need this!) Currently we only support blocks and some models - if (MoreCulling.CONFIG.useItemFrame3FaceCulling && - dist > MoreCulling.CONFIG.itemFrame3FaceCullingRange && - frame.rotation % 2 == 0 && - transformation.rotation.y() == 0 && - transformation.rotation.x() == 0 && - transformation.rotation.z() == 0 - ) { - int rotation = frame.rotation * 45; - Direction facing = frame.direction; - Direction dirX = shiftDirection(facing, - cameraPos.x > framePos.x ? Direction.EAST : Direction.WEST, rotation); - Direction dirY = shiftDirection(facing, - cameraPos.y > framePos.y ? Direction.UP : Direction.DOWN, rotation); - Direction dirZ = shiftDirection(facing, - cameraPos.z > framePos.z ? SOUTH : NORTH, rotation); - ItemRendererStates.DIRECTIONS = new Direction[] { dirX, dirY, dirZ }; - } else { - if (canCull) { - ItemRendererStates.DIRECTIONS = DirectionUtils.getAllDirectionsExcluding( - DirectionUtils.changeDirectionUsingTransformation(NORTH, transformation) - ); - } else { - ItemRendererStates.DIRECTIONS = null; - } - } - } - } -} diff --git a/neoforge/src/main/resources/moreculling.neoforge.mixins.json b/neoforge/src/main/resources/moreculling.neoforge.mixins.json index b4fb5259..268cc73c 100644 --- a/neoforge/src/main/resources/moreculling.neoforge.mixins.json +++ b/neoforge/src/main/resources/moreculling.neoforge.mixins.json @@ -6,11 +6,12 @@ "plugin": "ca.fxco.moreculling.config.MixinConfigPlugin", "client": [ "blockstates.Block_neoforgeDrawSideMixin", - "models.BakedModelWrapper_compatMixin", + "models.ItemModelGenerator_cullMixin", "models.MultiPartBakedModel_cacheMixin", "models.SimpleBakedModel_neoforgeCacheMixin", "models.WeightedBakedModel_cacheMixin", - "renderers.ItemRenderer_neoforgeFaceCullingMixin" + "models.cullshape.BlockModel_neoforgeCullShapeMixin", + "renderers.IBakedModelExtension_faceCullingMixin" ], "injectors": { "defaultRequire": 1