From cbca373fd829494fec740eb9321fe7398cf6ae63 Mon Sep 17 00:00:00 2001 From: IMS212 Date: Mon, 30 Dec 2024 12:06:31 -0800 Subject: [PATCH 1/3] Rewrite facade rendering --- .../client/ConduitFacadeRendering.java | 123 ++++++++++-------- .../client/model/ConduitBlockModel.java | 25 +--- .../model/conduit/facades/FacadeHelper.java | 30 +++-- .../facades/FacadeVisibilityHandler.java | 2 - .../mixin/BlockRenderDispatcherMixin.java | 23 ++++ .../resources/META-INF/neoforge.mods.toml | 3 + .../resources/enderioconduits.mixins.json | 9 ++ 7 files changed, 126 insertions(+), 89 deletions(-) create mode 100644 enderio-conduits/src/main/java/com/enderio/conduits/mixin/BlockRenderDispatcherMixin.java create mode 100644 enderio-conduits/src/main/resources/enderioconduits.mixins.json diff --git a/enderio-conduits/src/main/java/com/enderio/conduits/client/ConduitFacadeRendering.java b/enderio-conduits/src/main/java/com/enderio/conduits/client/ConduitFacadeRendering.java index 1c54c968c..84fb6029d 100644 --- a/enderio-conduits/src/main/java/com/enderio/conduits/client/ConduitFacadeRendering.java +++ b/enderio-conduits/src/main/java/com/enderio/conduits/client/ConduitFacadeRendering.java @@ -1,83 +1,100 @@ package com.enderio.conduits.client; import com.enderio.conduits.client.model.conduit.facades.FacadeHelper; -import com.enderio.conduits.common.conduit.block.ConduitBundleBlock; import com.enderio.conduits.common.conduit.block.ConduitBundleBlockEntity; import com.mojang.blaze3d.vertex.VertexConsumer; import java.util.Map; + +import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import net.minecraft.client.Minecraft; -import net.minecraft.client.multiplayer.ClientLevel; -import net.minecraft.client.renderer.LightTexture; -import net.minecraft.client.renderer.Sheets; +import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.texture.OverlayTexture; import net.minecraft.core.BlockPos; -import net.minecraft.util.FastColor; +import net.minecraft.core.SectionPos; import net.minecraft.util.RandomSource; -import net.minecraft.world.level.LightLayer; import net.minecraft.world.level.block.state.BlockState; +import net.minecraft.world.level.levelgen.SingleThreadedRandomSource; import net.neoforged.api.distmarker.Dist; import net.neoforged.bus.api.SubscribeEvent; import net.neoforged.fml.common.EventBusSubscriber; -import net.neoforged.neoforge.client.event.RenderLevelStageEvent; +import net.neoforged.neoforge.client.event.AddSectionGeometryEvent; import net.neoforged.neoforge.client.model.data.ModelData; import net.neoforged.neoforge.client.model.pipeline.VertexConsumerWrapper; @EventBusSubscriber(bus = EventBusSubscriber.Bus.GAME, value = Dist.CLIENT) public class ConduitFacadeRendering { + private static final ThreadLocal RANDOM = ThreadLocal.withInitial(() -> new SingleThreadedRandomSource(42L)); + @SubscribeEvent - static void renderFacade(RenderLevelStageEvent event) { - if (event.getStage() != RenderLevelStageEvent.Stage.AFTER_TRIPWIRE_BLOCKS || FacadeHelper.areFacadesVisible()) { - return; - } + static void renderFacade(AddSectionGeometryEvent event) { + Map facades = new Object2ObjectOpenHashMap<>(); + for (Map.Entry entry : ConduitBundleBlockEntity.FACADES.entrySet()) { - ClientLevel level = Minecraft.getInstance().level; - if (!level.isLoaded(entry.getKey())) { - return; + if (SectionPos.of(entry.getKey()).equals(SectionPos.of(event.getSectionOrigin()))) { + facades.put(entry.getKey(), entry.getValue()); } - if (level.getBlockState(entry.getKey()).getBlock() instanceof ConduitBundleBlock) { - if (entry.getValue() == null) { - continue; - } + } + + if (facades.isEmpty()) return; + + event.addRenderer(new FacadeRenderer(facades, FacadeHelper.areFacadesVisible())); + } + + private static class FacadeRenderer implements AddSectionGeometryEvent.AdditionalSectionRenderer { + private final Map facades; + private final boolean opaque; + + public FacadeRenderer(Map facades, boolean opaque) { + this.facades = facades; + this.opaque = opaque; + } - var baseConsumer = Minecraft.getInstance() - .renderBuffers() - .bufferSource() - .getBuffer(Sheets.translucentCullBlockSheet()); - var wrappedConsumer = new VertexConsumerWrapper(baseConsumer) { - @Override - public VertexConsumer setColor(int r, int g, int b, int a) { - super.setColor(r, g, b, 85); - return this; - } - }; - - var cameraPos = event.getCamera().getPosition(); - event.getPoseStack().pushPose(); - event.getPoseStack() - .translate(entry.getKey().getX() - cameraPos.x, entry.getKey().getY() - cameraPos.y, - entry.getKey().getZ() - cameraPos.z); + @Override + public void render(AddSectionGeometryEvent.SectionRenderingContext context) { + VertexConsumerWrapper wrapper = opaque ? null : new AlphaWrapper(context); + + RandomSource random = RANDOM.get(); + + for (Map.Entry entry : facades.entrySet()) { + context.getPoseStack().pushPose(); + context.getPoseStack() + .translate(entry.getKey().getX() & 15, + entry.getKey().getY() & 15, + entry.getKey().getZ() & 15); + + var state = entry.getValue(); + var pos = entry.getKey(); + + random.setSeed(42L); var model = Minecraft.getInstance() - .getModelManager() - .getBlockModelShaper() - .getBlockModel(entry.getValue()); - int color = Minecraft.getInstance().getBlockColors().getColor(entry.getValue(), level, entry.getKey()); - for (var renderType : model.getRenderTypes(entry.getValue(), RandomSource.create(), ModelData.EMPTY)) { - Minecraft.getInstance() - .getBlockRenderer() - .getModelRenderer() - .renderModel(event.getPoseStack().last(), wrappedConsumer, entry.getValue(), model, - FastColor.ARGB32.red(color) / 255.0F, FastColor.ARGB32.green(color) / 255.0F, - FastColor.ARGB32.blue(color) / 255.0F, - LightTexture.pack(level.getBrightness(LightLayer.BLOCK, entry.getKey()), - level.getBrightness(LightLayer.SKY, entry.getKey())), - OverlayTexture.NO_OVERLAY, - model.getModelData(level, entry.getKey(), entry.getValue(), ModelData.EMPTY), - renderType); + .getModelManager() + .getBlockModelShaper() + .getBlockModel(entry.getValue()); + + for (var renderType : model.getRenderTypes(entry.getValue(), random, ModelData.EMPTY)) { + VertexConsumer consumer = wrapper == null ? context.getOrCreateChunkBuffer(renderType) : wrapper; + Minecraft.getInstance().getBlockRenderer().getModelRenderer().tesselateBlock(context.getRegion(), + model, state, pos, context.getPoseStack(), + consumer, true, random, + 42L, OverlayTexture.NO_OVERLAY, + ModelData.EMPTY, renderType); } - Minecraft.getInstance().renderBuffers().bufferSource().endBatch(Sheets.translucentCullBlockSheet()); - event.getPoseStack().popPose(); + + context.getPoseStack().popPose(); + } + } + + private static class AlphaWrapper extends VertexConsumerWrapper { + public AlphaWrapper(AddSectionGeometryEvent.SectionRenderingContext context) { + super(context.getOrCreateChunkBuffer(RenderType.translucent())); + } + + @Override + public VertexConsumer setColor(int r, int g, int b, int a) { + super.setColor(r, g, b, 85); + return this; } } } diff --git a/enderio-conduits/src/main/java/com/enderio/conduits/client/model/ConduitBlockModel.java b/enderio-conduits/src/main/java/com/enderio/conduits/client/model/ConduitBlockModel.java index 795b9a5fb..7748f2b10 100644 --- a/enderio-conduits/src/main/java/com/enderio/conduits/client/model/ConduitBlockModel.java +++ b/enderio-conduits/src/main/java/com/enderio/conduits/client/model/ConduitBlockModel.java @@ -71,28 +71,14 @@ public List getQuads(@Nullable BlockState state, @Nullable Direction List quads = new ArrayList<>(); ConduitBundle conduitBundle = extraData.get(ConduitBundleBlockEntity.BUNDLE_MODEL_PROPERTY); - ModelData data = extraData.get(ConduitBundleBlockEntity.FACADE_MODEL_DATA); if (conduitBundle != null) { if (FacadeHelper.areFacadesVisible()) { - IQuadTransformer transformer = quad -> quad.tintIndex = ConduitFacadeColor - .moveTintIndex(quad.getTintIndex()); - Optional facadeOpt = conduitBundle.facade(); - if (facadeOpt.isPresent()) { - BlockState facade = facadeOpt.get().defaultBlockState(); - var model = Minecraft.getInstance().getBlockRenderer().getBlockModel(facade); - var facadeQuads = model.getQuads(facade, side, rand, data, renderType); - - if (renderType != null && model.getRenderTypes(facade, rand, data).contains(renderType)) { - quads.addAll(transformer.process(facadeQuads)); - } - } - // If the facade should hide the conduits, escape early. if (conduitBundle.hasFacade()) { boolean areConduitsHidden = conduitBundle.facadeType() - .map(FacadeType::doesHideConduits) - .orElse(false); + .map(FacadeType::doesHideConduits) + .orElse(false); if (areConduitsHidden) { return quads; @@ -340,12 +326,7 @@ public ItemOverrides getOverrides() { @Override public ChunkRenderTypeSet getRenderTypes(@NotNull BlockState state, @NotNull RandomSource rand, @NotNull ModelData data) { - ChunkRenderTypeSet facadeRenderTypes = data.get(ConduitBundleBlockEntity.FACADE_RENDERTYPE); - ChunkRenderTypeSet renderTypes = ChunkRenderTypeSet.of(RenderType.cutout()); - if (facadeRenderTypes != null) { - renderTypes = ChunkRenderTypeSet.union(renderTypes, facadeRenderTypes); - } - return renderTypes; + return ChunkRenderTypeSet.of(RenderType.cutout()); } @Override diff --git a/enderio-conduits/src/main/java/com/enderio/conduits/client/model/conduit/facades/FacadeHelper.java b/enderio-conduits/src/main/java/com/enderio/conduits/client/model/conduit/facades/FacadeHelper.java index 2a3b98a41..2312810a1 100644 --- a/enderio-conduits/src/main/java/com/enderio/conduits/client/model/conduit/facades/FacadeHelper.java +++ b/enderio-conduits/src/main/java/com/enderio/conduits/client/model/conduit/facades/FacadeHelper.java @@ -1,6 +1,12 @@ package com.enderio.conduits.client.model.conduit.facades; +import com.enderio.conduits.common.conduit.block.ConduitBundleBlockEntity; +import com.mojang.blaze3d.systems.RenderSystem; import net.minecraft.client.Minecraft; +import net.minecraft.core.SectionPos; + +import java.util.HashSet; +import java.util.Set; // TODO: In future, support hiding specific conduit types too. public class FacadeHelper { @@ -8,22 +14,22 @@ public class FacadeHelper { private static boolean FACADES_VISIBLE = true; public static void setFacadesVisible(boolean visible) { + if (visible != FACADES_VISIBLE) { + Set facadeSections = new HashSet<>(); + + ConduitBundleBlockEntity.FACADES.keySet().forEach((pos) -> facadeSections.add(SectionPos.of(pos))); + + RenderSystem.recordRenderCall(() -> { + facadeSections.forEach((section) -> { + Minecraft.getInstance().levelRenderer.setSectionDirty(section.x(), section.y(), section.z()); + }); + }); + } + FACADES_VISIBLE = visible; } public static boolean areFacadesVisible() { return FACADES_VISIBLE; } - - public static void rebuildChunkMeshes() { - var minecraft = Minecraft.getInstance(); - - if (minecraft.levelRenderer.viewArea == null) { - return; - } - - for (var section : minecraft.levelRenderer.viewArea.sections) { - section.setDirty(false); - } - } } diff --git a/enderio-conduits/src/main/java/com/enderio/conduits/client/model/conduit/facades/FacadeVisibilityHandler.java b/enderio-conduits/src/main/java/com/enderio/conduits/client/model/conduit/facades/FacadeVisibilityHandler.java index bca9cb3d2..f03e87bc3 100644 --- a/enderio-conduits/src/main/java/com/enderio/conduits/client/model/conduit/facades/FacadeVisibilityHandler.java +++ b/enderio-conduits/src/main/java/com/enderio/conduits/client/model/conduit/facades/FacadeVisibilityHandler.java @@ -26,8 +26,6 @@ public static void onEquipmentChanged(LivingEquipmentChangeEvent event) { ItemStack offHand = event.getEntity().getItemBySlot(EquipmentSlot.OFFHAND); FacadeHelper.setFacadesVisible( !mainHand.is(EIOTags.Items.HIDE_FACADES) && !offHand.is(EIOTags.Items.HIDE_FACADES)); - - FacadeHelper.rebuildChunkMeshes(); } } } diff --git a/enderio-conduits/src/main/java/com/enderio/conduits/mixin/BlockRenderDispatcherMixin.java b/enderio-conduits/src/main/java/com/enderio/conduits/mixin/BlockRenderDispatcherMixin.java new file mode 100644 index 000000000..ac44d13e5 --- /dev/null +++ b/enderio-conduits/src/main/java/com/enderio/conduits/mixin/BlockRenderDispatcherMixin.java @@ -0,0 +1,23 @@ +package com.enderio.conduits.mixin; + +import com.enderio.conduits.common.conduit.block.ConduitBundleBlockEntity; +import com.llamalad7.mixinextras.injector.wrapoperation.Operation; +import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation; +import net.minecraft.client.renderer.block.BlockModelShaper; +import net.minecraft.client.renderer.block.BlockRenderDispatcher; +import net.minecraft.client.resources.model.BakedModel; +import net.minecraft.core.BlockPos; +import net.minecraft.world.level.BlockAndTintGetter; +import net.minecraft.world.level.block.state.BlockState; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +@Mixin(BlockRenderDispatcher.class) +public class BlockRenderDispatcherMixin { + @WrapOperation(method = "renderBreakingTexture(Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/BlockAndTintGetter;Lcom/mojang/blaze3d/vertex/PoseStack;Lcom/mojang/blaze3d/vertex/VertexConsumer;Lnet/neoforged/neoforge/client/model/data/ModelData;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/block/BlockModelShaper;getBlockModel(Lnet/minecraft/world/level/block/state/BlockState;)Lnet/minecraft/client/resources/model/BakedModel;")) + public BakedModel enderio$checkFacades(BlockModelShaper instance, BlockState state, Operation original, BlockState localState, BlockPos pos, BlockAndTintGetter level) { + BlockState facadeState = ConduitBundleBlockEntity.FACADES.getOrDefault(pos, null); + + return original.call(instance, facadeState == null ? state : facadeState); + } +} diff --git a/enderio-conduits/src/main/resources/META-INF/neoforge.mods.toml b/enderio-conduits/src/main/resources/META-INF/neoforge.mods.toml index 0eb9c82af..08663c107 100644 --- a/enderio-conduits/src/main/resources/META-INF/neoforge.mods.toml +++ b/enderio-conduits/src/main/resources/META-INF/neoforge.mods.toml @@ -12,6 +12,9 @@ description="The conduits module for Ender IO" displayURL="https://enderio.com/" logoFile="logo.png" +[[mixins]] +config="enderioconduits.mixins.json" + [[dependencies.enderio_conduits]] modId="minecraft" type="required" diff --git a/enderio-conduits/src/main/resources/enderioconduits.mixins.json b/enderio-conduits/src/main/resources/enderioconduits.mixins.json new file mode 100644 index 000000000..a62b86193 --- /dev/null +++ b/enderio-conduits/src/main/resources/enderioconduits.mixins.json @@ -0,0 +1,9 @@ +{ + "required" : true, + "package" : "com.enderio.conduits.mixin", + "compatibilityLevel" : "JAVA_17", + "client" : [ + "BlockRenderDispatcherMixin" + ], + "minVersion" : "0.8" +} From 4a8d45e6614300fe85f65c76fc1c9bb12593969d Mon Sep 17 00:00:00 2001 From: IMS212 Date: Mon, 30 Dec 2024 12:10:00 -0800 Subject: [PATCH 2/3] Fix spotless --- .../client/ConduitFacadeRendering.java | 29 +++++++++---------- .../client/model/ConduitBlockModel.java | 7 ++--- .../model/conduit/facades/FacadeHelper.java | 5 ++-- .../mixin/BlockRenderDispatcherMixin.java | 3 +- 4 files changed, 20 insertions(+), 24 deletions(-) diff --git a/enderio-conduits/src/main/java/com/enderio/conduits/client/ConduitFacadeRendering.java b/enderio-conduits/src/main/java/com/enderio/conduits/client/ConduitFacadeRendering.java index 84fb6029d..68343eded 100644 --- a/enderio-conduits/src/main/java/com/enderio/conduits/client/ConduitFacadeRendering.java +++ b/enderio-conduits/src/main/java/com/enderio/conduits/client/ConduitFacadeRendering.java @@ -3,9 +3,8 @@ import com.enderio.conduits.client.model.conduit.facades.FacadeHelper; import com.enderio.conduits.common.conduit.block.ConduitBundleBlockEntity; import com.mojang.blaze3d.vertex.VertexConsumer; -import java.util.Map; - import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; +import java.util.Map; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.texture.OverlayTexture; @@ -24,7 +23,8 @@ @EventBusSubscriber(bus = EventBusSubscriber.Bus.GAME, value = Dist.CLIENT) public class ConduitFacadeRendering { - private static final ThreadLocal RANDOM = ThreadLocal.withInitial(() -> new SingleThreadedRandomSource(42L)); + private static final ThreadLocal RANDOM = ThreadLocal + .withInitial(() -> new SingleThreadedRandomSource(42L)); @SubscribeEvent static void renderFacade(AddSectionGeometryEvent event) { @@ -36,7 +36,8 @@ static void renderFacade(AddSectionGeometryEvent event) { } } - if (facades.isEmpty()) return; + if (facades.isEmpty()) + return; event.addRenderer(new FacadeRenderer(facades, FacadeHelper.areFacadesVisible())); } @@ -59,9 +60,7 @@ public void render(AddSectionGeometryEvent.SectionRenderingContext context) { for (Map.Entry entry : facades.entrySet()) { context.getPoseStack().pushPose(); context.getPoseStack() - .translate(entry.getKey().getX() & 15, - entry.getKey().getY() & 15, - entry.getKey().getZ() & 15); + .translate(entry.getKey().getX() & 15, entry.getKey().getY() & 15, entry.getKey().getZ() & 15); var state = entry.getValue(); var pos = entry.getKey(); @@ -69,17 +68,17 @@ public void render(AddSectionGeometryEvent.SectionRenderingContext context) { random.setSeed(42L); var model = Minecraft.getInstance() - .getModelManager() - .getBlockModelShaper() - .getBlockModel(entry.getValue()); + .getModelManager() + .getBlockModelShaper() + .getBlockModel(entry.getValue()); for (var renderType : model.getRenderTypes(entry.getValue(), random, ModelData.EMPTY)) { VertexConsumer consumer = wrapper == null ? context.getOrCreateChunkBuffer(renderType) : wrapper; - Minecraft.getInstance().getBlockRenderer().getModelRenderer().tesselateBlock(context.getRegion(), - model, state, pos, context.getPoseStack(), - consumer, true, random, - 42L, OverlayTexture.NO_OVERLAY, - ModelData.EMPTY, renderType); + Minecraft.getInstance() + .getBlockRenderer() + .getModelRenderer() + .tesselateBlock(context.getRegion(), model, state, pos, context.getPoseStack(), consumer, + true, random, 42L, OverlayTexture.NO_OVERLAY, ModelData.EMPTY, renderType); } context.getPoseStack().popPose(); diff --git a/enderio-conduits/src/main/java/com/enderio/conduits/client/model/ConduitBlockModel.java b/enderio-conduits/src/main/java/com/enderio/conduits/client/model/ConduitBlockModel.java index 7748f2b10..16ea0f683 100644 --- a/enderio-conduits/src/main/java/com/enderio/conduits/client/model/ConduitBlockModel.java +++ b/enderio-conduits/src/main/java/com/enderio/conduits/client/model/ConduitBlockModel.java @@ -16,7 +16,6 @@ import com.enderio.conduits.api.ConduitNode; import com.enderio.conduits.api.facade.FacadeType; import com.enderio.conduits.api.model.ConduitCoreModelModifier; -import com.enderio.conduits.client.ConduitFacadeColor; import com.enderio.conduits.client.model.conduit.facades.FacadeHelper; import com.enderio.conduits.client.model.conduit.modifier.ConduitCoreModelModifiers; import com.enderio.conduits.common.Area; @@ -34,7 +33,6 @@ import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.Optional; import java.util.Set; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.RenderType; @@ -50,7 +48,6 @@ import net.minecraft.util.RandomSource; import net.minecraft.world.inventory.InventoryMenu; import net.minecraft.world.level.BlockAndTintGetter; -import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.state.BlockState; import net.minecraft.world.level.levelgen.SingleThreadedRandomSource; import net.neoforged.neoforge.client.ChunkRenderTypeSet; @@ -77,8 +74,8 @@ public List getQuads(@Nullable BlockState state, @Nullable Direction // If the facade should hide the conduits, escape early. if (conduitBundle.hasFacade()) { boolean areConduitsHidden = conduitBundle.facadeType() - .map(FacadeType::doesHideConduits) - .orElse(false); + .map(FacadeType::doesHideConduits) + .orElse(false); if (areConduitsHidden) { return quads; diff --git a/enderio-conduits/src/main/java/com/enderio/conduits/client/model/conduit/facades/FacadeHelper.java b/enderio-conduits/src/main/java/com/enderio/conduits/client/model/conduit/facades/FacadeHelper.java index 2312810a1..22dd6b8a5 100644 --- a/enderio-conduits/src/main/java/com/enderio/conduits/client/model/conduit/facades/FacadeHelper.java +++ b/enderio-conduits/src/main/java/com/enderio/conduits/client/model/conduit/facades/FacadeHelper.java @@ -2,11 +2,10 @@ import com.enderio.conduits.common.conduit.block.ConduitBundleBlockEntity; import com.mojang.blaze3d.systems.RenderSystem; -import net.minecraft.client.Minecraft; -import net.minecraft.core.SectionPos; - import java.util.HashSet; import java.util.Set; +import net.minecraft.client.Minecraft; +import net.minecraft.core.SectionPos; // TODO: In future, support hiding specific conduit types too. public class FacadeHelper { diff --git a/enderio-conduits/src/main/java/com/enderio/conduits/mixin/BlockRenderDispatcherMixin.java b/enderio-conduits/src/main/java/com/enderio/conduits/mixin/BlockRenderDispatcherMixin.java index ac44d13e5..1043d0c6f 100644 --- a/enderio-conduits/src/main/java/com/enderio/conduits/mixin/BlockRenderDispatcherMixin.java +++ b/enderio-conduits/src/main/java/com/enderio/conduits/mixin/BlockRenderDispatcherMixin.java @@ -15,7 +15,8 @@ @Mixin(BlockRenderDispatcher.class) public class BlockRenderDispatcherMixin { @WrapOperation(method = "renderBreakingTexture(Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/BlockAndTintGetter;Lcom/mojang/blaze3d/vertex/PoseStack;Lcom/mojang/blaze3d/vertex/VertexConsumer;Lnet/neoforged/neoforge/client/model/data/ModelData;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/block/BlockModelShaper;getBlockModel(Lnet/minecraft/world/level/block/state/BlockState;)Lnet/minecraft/client/resources/model/BakedModel;")) - public BakedModel enderio$checkFacades(BlockModelShaper instance, BlockState state, Operation original, BlockState localState, BlockPos pos, BlockAndTintGetter level) { + public BakedModel enderio$checkFacades(BlockModelShaper instance, BlockState state, Operation original, + BlockState localState, BlockPos pos, BlockAndTintGetter level) { BlockState facadeState = ConduitBundleBlockEntity.FACADES.getOrDefault(pos, null); return original.call(instance, facadeState == null ? state : facadeState); From 7069cd4adf264f905664b41992e3d1ded5514a05 Mon Sep 17 00:00:00 2001 From: IMS212 Date: Mon, 30 Dec 2024 12:35:27 -0800 Subject: [PATCH 3/3] Add chunk map --- .../client/ConduitFacadeRendering.java | 14 +++++++++---- .../model/conduit/facades/FacadeHelper.java | 11 +++------- .../block/ConduitBundleBlockEntity.java | 20 +++++++++++++++---- .../mixin/BlockRenderDispatcherMixin.java | 2 +- 4 files changed, 30 insertions(+), 17 deletions(-) diff --git a/enderio-conduits/src/main/java/com/enderio/conduits/client/ConduitFacadeRendering.java b/enderio-conduits/src/main/java/com/enderio/conduits/client/ConduitFacadeRendering.java index 68343eded..99215d377 100644 --- a/enderio-conduits/src/main/java/com/enderio/conduits/client/ConduitFacadeRendering.java +++ b/enderio-conduits/src/main/java/com/enderio/conduits/client/ConduitFacadeRendering.java @@ -5,6 +5,7 @@ import com.mojang.blaze3d.vertex.VertexConsumer; import it.unimi.dsi.fastutil.objects.Object2ObjectOpenHashMap; import java.util.Map; +import java.util.Set; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.RenderType; import net.minecraft.client.renderer.texture.OverlayTexture; @@ -30,10 +31,15 @@ public class ConduitFacadeRendering { static void renderFacade(AddSectionGeometryEvent event) { Map facades = new Object2ObjectOpenHashMap<>(); - for (Map.Entry entry : ConduitBundleBlockEntity.FACADES.entrySet()) { - if (SectionPos.of(entry.getKey()).equals(SectionPos.of(event.getSectionOrigin()))) { - facades.put(entry.getKey(), entry.getValue()); - } + Set blockList = ConduitBundleBlockEntity.CHUNK_FACADES + .getOrDefault(SectionPos.asLong(event.getSectionOrigin()), null); + + if (blockList == null) { + return; + } + + for (BlockPos entry : blockList) { + facades.put(entry, ConduitBundleBlockEntity.FACADES.get(entry.asLong())); } if (facades.isEmpty()) diff --git a/enderio-conduits/src/main/java/com/enderio/conduits/client/model/conduit/facades/FacadeHelper.java b/enderio-conduits/src/main/java/com/enderio/conduits/client/model/conduit/facades/FacadeHelper.java index 22dd6b8a5..67c21bc73 100644 --- a/enderio-conduits/src/main/java/com/enderio/conduits/client/model/conduit/facades/FacadeHelper.java +++ b/enderio-conduits/src/main/java/com/enderio/conduits/client/model/conduit/facades/FacadeHelper.java @@ -2,8 +2,6 @@ import com.enderio.conduits.common.conduit.block.ConduitBundleBlockEntity; import com.mojang.blaze3d.systems.RenderSystem; -import java.util.HashSet; -import java.util.Set; import net.minecraft.client.Minecraft; import net.minecraft.core.SectionPos; @@ -14,13 +12,10 @@ public class FacadeHelper { public static void setFacadesVisible(boolean visible) { if (visible != FACADES_VISIBLE) { - Set facadeSections = new HashSet<>(); - - ConduitBundleBlockEntity.FACADES.keySet().forEach((pos) -> facadeSections.add(SectionPos.of(pos))); - RenderSystem.recordRenderCall(() -> { - facadeSections.forEach((section) -> { - Minecraft.getInstance().levelRenderer.setSectionDirty(section.x(), section.y(), section.z()); + ConduitBundleBlockEntity.CHUNK_FACADES.keySet().forEach((section) -> { + Minecraft.getInstance().levelRenderer.setSectionDirty(SectionPos.x(section), SectionPos.y(section), + SectionPos.z(section)); }); }); } diff --git a/enderio-conduits/src/main/java/com/enderio/conduits/common/conduit/block/ConduitBundleBlockEntity.java b/enderio-conduits/src/main/java/com/enderio/conduits/common/conduit/block/ConduitBundleBlockEntity.java index 9966529db..1b5284536 100644 --- a/enderio-conduits/src/main/java/com/enderio/conduits/common/conduit/block/ConduitBundleBlockEntity.java +++ b/enderio-conduits/src/main/java/com/enderio/conduits/common/conduit/block/ConduitBundleBlockEntity.java @@ -29,6 +29,9 @@ import com.enderio.core.common.blockentity.EnderBlockEntity; import dev.gigaherz.graph3.Graph; import dev.gigaherz.graph3.GraphObject; +import it.unimi.dsi.fastutil.longs.Long2ObjectMap; +import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap; +import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -43,6 +46,7 @@ import net.minecraft.core.Direction; import net.minecraft.core.Holder; import net.minecraft.core.HolderLookup; +import net.minecraft.core.SectionPos; import net.minecraft.nbt.CompoundTag; import net.minecraft.nbt.ListTag; import net.minecraft.nbt.Tag; @@ -79,7 +83,8 @@ public class ConduitBundleBlockEntity extends EnderBlockEntity { public static final String CONDUIT_INV_KEY = "ConduitInv"; @UseOnly(LogicalSide.CLIENT) - public static final Map FACADES = new HashMap<>(); + public static final Long2ObjectMap FACADES = new Long2ObjectOpenHashMap<>(); + public static final Long2ObjectMap> CHUNK_FACADES = new Long2ObjectOpenHashMap<>(); private final ConduitShape shape = new ConduitShape(); @@ -120,9 +125,15 @@ public void updateClient() { requestModelDataUpdate(); level.setBlocksDirty(getBlockPos(), Blocks.AIR.defaultBlockState(), getBlockState()); if (bundle.hasFacade()) { - FACADES.put(worldPosition, bundle.facade().get().defaultBlockState()); + FACADES.put(worldPosition.asLong(), bundle.facade().get().defaultBlockState()); + CHUNK_FACADES.computeIfAbsent(SectionPos.asLong(worldPosition), p -> new ObjectOpenHashSet<>()) + .add(worldPosition); } else { - FACADES.remove(worldPosition); + FACADES.remove(worldPosition.asLong()); + Set chunkList = CHUNK_FACADES.getOrDefault(SectionPos.asLong(worldPosition), null); + if (chunkList != null) { + chunkList.remove(worldPosition); + } } } } @@ -217,7 +228,8 @@ public void onChunkUnloaded() { ConduitSavedData savedData = ConduitSavedData.get(serverLevel); bundle.getConduits().forEach(type -> onChunkUnloaded(savedData, type)); } else { - FACADES.remove(worldPosition); + CHUNK_FACADES.remove(SectionPos.asLong(worldPosition)); + FACADES.remove(worldPosition.asLong()); } } diff --git a/enderio-conduits/src/main/java/com/enderio/conduits/mixin/BlockRenderDispatcherMixin.java b/enderio-conduits/src/main/java/com/enderio/conduits/mixin/BlockRenderDispatcherMixin.java index 1043d0c6f..4d4bf6bdd 100644 --- a/enderio-conduits/src/main/java/com/enderio/conduits/mixin/BlockRenderDispatcherMixin.java +++ b/enderio-conduits/src/main/java/com/enderio/conduits/mixin/BlockRenderDispatcherMixin.java @@ -17,7 +17,7 @@ public class BlockRenderDispatcherMixin { @WrapOperation(method = "renderBreakingTexture(Lnet/minecraft/world/level/block/state/BlockState;Lnet/minecraft/core/BlockPos;Lnet/minecraft/world/level/BlockAndTintGetter;Lcom/mojang/blaze3d/vertex/PoseStack;Lcom/mojang/blaze3d/vertex/VertexConsumer;Lnet/neoforged/neoforge/client/model/data/ModelData;)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/block/BlockModelShaper;getBlockModel(Lnet/minecraft/world/level/block/state/BlockState;)Lnet/minecraft/client/resources/model/BakedModel;")) public BakedModel enderio$checkFacades(BlockModelShaper instance, BlockState state, Operation original, BlockState localState, BlockPos pos, BlockAndTintGetter level) { - BlockState facadeState = ConduitBundleBlockEntity.FACADES.getOrDefault(pos, null); + BlockState facadeState = ConduitBundleBlockEntity.FACADES.getOrDefault(pos.asLong(), null); return original.call(instance, facadeState == null ? state : facadeState); }