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