From 21077410ff6b88f947ffd8112e07bc3afe3279b5 Mon Sep 17 00:00:00 2001 From: PepperCode1 <44146161+PepperCode1@users.noreply.github.com> Date: Fri, 27 Dec 2024 10:36:50 -0800 Subject: [PATCH] Port to 1.21.4 --- gradle.properties | 12 +- gradle/wrapper/gradle-wrapper.properties | 2 +- .../continuity/api/client/QuadProcessor.java | 8 - .../client/config/ContinuityConfig.java | 1 - .../client/mixin/BakedModelManagerMixin.java | 26 +++- .../client/mixin/LayerRenderStateMixin.java | 21 +++ .../client/model/CtmBakedModel.java | 47 +++--- .../client/model/EmissiveBakedModel.java | 101 +++++------- .../client/model/ModelObjectsContainer.java | 6 +- .../processor/CompactCtmQuadProcessor.java | 2 - .../client/processor/ProcessingDataKeys.java | 4 +- .../overlay/SimpleOverlayQuadProcessor.java | 47 +----- .../overlay/StandardOverlayQuadProcessor.java | 144 +++++++----------- .../BakedModelManagerBakeContext.java | 12 ++ .../BakedModelManagerReloadExtension.java | 5 +- .../client/resource/ModelWrappingHandler.java | 44 ++++-- .../continuity/client/util/RenderUtil.java | 4 +- .../impl/client/ProcessingContextImpl.java | 53 +------ src/main/resources/continuity.mixins.json | 1 + src/main/resources/fabric.mod.json | 6 +- .../resourcepacks/default/pack.mcmeta | 4 +- .../glass_pane_culling_fix/pack.mcmeta | 4 +- 22 files changed, 234 insertions(+), 320 deletions(-) create mode 100644 src/main/java/me/pepperbell/continuity/client/mixin/LayerRenderStateMixin.java create mode 100644 src/main/java/me/pepperbell/continuity/client/resource/BakedModelManagerBakeContext.java diff --git a/gradle.properties b/gradle.properties index 72daa0de..101fa78c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -3,17 +3,17 @@ org.gradle.jvmargs = -Xmx1G org.gradle.parallel = true # Fabric Properties -loom_version = 1.8.12 -minecraft_version = 1.21.3 -yarn_mappings = 1.21.3+build.2 +loom_version = 1.9.2 +minecraft_version = 1.21.4 +yarn_mappings = 1.21.4+build.1 loader_version = 0.16.9 # Mod Properties mod_version = 3.0.0 -mod_minecraft_version = 1.21.3 +mod_minecraft_version = 1.21.4 maven_group = me.pepperbell archives_base_name = continuity # Dependencies -fabric_version = 0.107.3+1.21.3 -modmenu_version = 12.0.0-beta.1 +fabric_version = 0.113.0+1.21.4 +modmenu_version = 13.0.0-beta.1 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index df97d72b..e2847c82 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/src/main/java/me/pepperbell/continuity/api/client/QuadProcessor.java b/src/main/java/me/pepperbell/continuity/api/client/QuadProcessor.java index 80b32922..c701c457 100644 --- a/src/main/java/me/pepperbell/continuity/api/client/QuadProcessor.java +++ b/src/main/java/me/pepperbell/continuity/api/client/QuadProcessor.java @@ -1,10 +1,8 @@ package me.pepperbell.continuity.api.client; -import java.util.function.Consumer; import java.util.function.Function; import java.util.function.Supplier; -import net.fabricmc.fabric.api.renderer.v1.mesh.Mesh; import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView; import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter; import net.minecraft.block.BlockState; @@ -18,13 +16,7 @@ public interface QuadProcessor { ProcessingResult processQuad(MutableQuadView quad, Sprite sprite, BlockRenderView blockView, BlockState appearanceState, BlockState state, BlockPos pos, Supplier randomSupplier, int pass, ProcessingContext context); interface ProcessingContext extends ProcessingDataProvider { - void addEmitterConsumer(Consumer consumer); - - void addMesh(Mesh mesh); - QuadEmitter getExtraQuadEmitter(); - - void markHasExtraQuads(); } enum ProcessingResult { diff --git a/src/main/java/me/pepperbell/continuity/client/config/ContinuityConfig.java b/src/main/java/me/pepperbell/continuity/client/config/ContinuityConfig.java index f7a6ac6a..4210def4 100644 --- a/src/main/java/me/pepperbell/continuity/client/config/ContinuityConfig.java +++ b/src/main/java/me/pepperbell/continuity/client/config/ContinuityConfig.java @@ -38,7 +38,6 @@ public class ContinuityConfig { public final Option.BooleanOption connectedTextures = addOption(new Option.BooleanOption("connected_textures", true)); public final Option.BooleanOption emissiveTextures = addOption(new Option.BooleanOption("emissive_textures", true)); public final Option.BooleanOption customBlockLayers = addOption(new Option.BooleanOption("custom_block_layers", true)); - public final Option.BooleanOption useManualCulling = addOption(new Option.BooleanOption("use_manual_culling", true)); public ContinuityConfig(File file) { this.file = file; diff --git a/src/main/java/me/pepperbell/continuity/client/mixin/BakedModelManagerMixin.java b/src/main/java/me/pepperbell/continuity/client/mixin/BakedModelManagerMixin.java index 33d22bc7..16dee7e4 100644 --- a/src/main/java/me/pepperbell/continuity/client/mixin/BakedModelManagerMixin.java +++ b/src/main/java/me/pepperbell/continuity/client/mixin/BakedModelManagerMixin.java @@ -3,20 +3,26 @@ import java.util.Map; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; +import java.util.function.Function; import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Mixin; 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.ModifyArg; +import org.spongepowered.asm.mixin.injection.Slice; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import com.llamalad7.mixinextras.injector.ModifyReturnValue; import it.unimi.dsi.fastutil.objects.Object2IntMap; +import me.pepperbell.continuity.client.resource.BakedModelManagerBakeContext; import me.pepperbell.continuity.client.resource.BakedModelManagerReloadExtension; import net.minecraft.block.BlockState; +import net.minecraft.client.render.block.entity.LoadedBlockEntityModels; +import net.minecraft.client.render.entity.model.LoadedEntityModels; import net.minecraft.client.render.model.BakedModelManager; import net.minecraft.client.render.model.ModelBaker; import net.minecraft.client.render.model.SpriteAtlasManager; @@ -54,11 +60,25 @@ abstract class BakedModelManagerMixin { return original.thenRun(() -> continuity$reloadExtension = null); } - @Inject(method = "bake(Lnet/minecraft/util/profiler/Profiler;Ljava/util/Map;Lnet/minecraft/client/render/model/ModelBaker;Lit/unimi/dsi/fastutil/objects/Object2IntMap;)Lnet/minecraft/client/render/model/BakedModelManager$BakingResult;", at = @At("HEAD")) - private void continuity$onHeadBake(Profiler profiler, Map preparations, ModelBaker bakery, Object2IntMap modelGroups, CallbackInfoReturnable cir) { + @ModifyArg(method = "reload(Lnet/minecraft/resource/ResourceReloader$Synchronizer;Lnet/minecraft/resource/ResourceManager;Ljava/util/concurrent/Executor;Ljava/util/concurrent/Executor;)Ljava/util/concurrent/CompletableFuture;", slice = @Slice(from = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/model/SpriteAtlasManager;reload(Lnet/minecraft/resource/ResourceManager;ILjava/util/concurrent/Executor;)Ljava/util/Map;")), at = @At(value = "INVOKE", target = "Ljava/util/concurrent/CompletableFuture;thenApplyAsync(Ljava/util/function/Function;Ljava/util/concurrent/Executor;)Ljava/util/concurrent/CompletableFuture;", ordinal = 0), index = 0) + private Function continuity$modifyFunction(Function function) { BakedModelManagerReloadExtension reloadExtension = continuity$reloadExtension; if (reloadExtension != null) { - reloadExtension.beforeBaking(preparations); + return v -> { + BakedModelManagerBakeContext.THREAD_LOCAL.set(reloadExtension); + Object result = function.apply(v); + BakedModelManagerBakeContext.THREAD_LOCAL.remove(); + return result; + }; + } + return function; + } + + @Inject(method = "bake(Lnet/minecraft/util/profiler/Profiler;Ljava/util/Map;Lnet/minecraft/client/render/model/ModelBaker;Lit/unimi/dsi/fastutil/objects/Object2IntMap;Lnet/minecraft/client/render/entity/model/LoadedEntityModels;Lnet/minecraft/client/render/block/entity/LoadedBlockEntityModels;)Lnet/minecraft/client/render/model/BakedModelManager$BakingResult;", at = @At("HEAD")) + private static void continuity$onHeadBake(Profiler profiler, final Map atlases, ModelBaker baker, Object2IntMap groups, LoadedEntityModels entityModels, LoadedBlockEntityModels blockEntityModels, CallbackInfoReturnable cir) { + BakedModelManagerBakeContext context = BakedModelManagerBakeContext.THREAD_LOCAL.get(); + if (context != null) { + context.beforeBake(atlases); } } diff --git a/src/main/java/me/pepperbell/continuity/client/mixin/LayerRenderStateMixin.java b/src/main/java/me/pepperbell/continuity/client/mixin/LayerRenderStateMixin.java new file mode 100644 index 00000000..f7be95a1 --- /dev/null +++ b/src/main/java/me/pepperbell/continuity/client/mixin/LayerRenderStateMixin.java @@ -0,0 +1,21 @@ +package me.pepperbell.continuity.client.mixin; + +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.ModifyVariable; + +import me.pepperbell.continuity.client.resource.ModelWrappingHandler; +import net.minecraft.client.render.item.ItemRenderState; +import net.minecraft.client.render.model.BakedModel; + +@Mixin(value = ItemRenderState.LayerRenderState.class, priority = -1000) +abstract class LayerRenderStateMixin { + @ModifyVariable(method = "setModel(Lnet/minecraft/client/render/model/BakedModel;Lnet/minecraft/client/render/RenderLayer;)V", at = @At("HEAD"), argsOnly = true, ordinal = 0) + private BakedModel continuity$modifyBakedModel(BakedModel model) { + ModelWrappingHandler wrappingHandler = ModelWrappingHandler.getInstance(); + if (wrappingHandler != null) { + return wrappingHandler.ensureWrapped(model); + } + return model; + } +} diff --git a/src/main/java/me/pepperbell/continuity/client/model/CtmBakedModel.java b/src/main/java/me/pepperbell/continuity/client/model/CtmBakedModel.java index e37d9720..2948f602 100644 --- a/src/main/java/me/pepperbell/continuity/client/model/CtmBakedModel.java +++ b/src/main/java/me/pepperbell/continuity/client/model/CtmBakedModel.java @@ -1,50 +1,54 @@ package me.pepperbell.continuity.client.model; import java.util.function.Function; +import java.util.function.Predicate; import java.util.function.Supplier; +import org.jetbrains.annotations.Nullable; + import me.pepperbell.continuity.api.client.QuadProcessor; import me.pepperbell.continuity.client.config.ContinuityConfig; import me.pepperbell.continuity.client.util.RenderUtil; import me.pepperbell.continuity.impl.client.ProcessingContextImpl; import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView; -import net.fabricmc.fabric.api.renderer.v1.model.ForwardingBakedModel; -import net.fabricmc.fabric.api.renderer.v1.render.RenderContext; +import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter; +import net.fabricmc.fabric.api.renderer.v1.mesh.QuadTransform; import net.minecraft.block.BlockState; import net.minecraft.client.render.model.BakedModel; +import net.minecraft.client.render.model.WrapperBakedModel; import net.minecraft.client.texture.Sprite; import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.Direction; import net.minecraft.util.math.random.Random; import net.minecraft.world.BlockRenderView; -public class CtmBakedModel extends ForwardingBakedModel { +public class CtmBakedModel extends WrapperBakedModel { public static final int PASSES = 4; protected final BlockState defaultState; protected volatile Function defaultSliceFunc; public CtmBakedModel(BakedModel wrapped, BlockState defaultState) { - this.wrapped = wrapped; + super(wrapped); this.defaultState = defaultState; } @Override - public void emitBlockQuads(BlockRenderView blockView, BlockState state, BlockPos pos, Supplier randomSupplier, RenderContext context) { + public void emitBlockQuads(QuadEmitter emitter, BlockRenderView blockView, BlockState state, BlockPos pos, Supplier randomSupplier, Predicate<@Nullable Direction> cullTest) { if (!ContinuityConfig.INSTANCE.connectedTextures.get()) { - super.emitBlockQuads(blockView, state, pos, randomSupplier, context); + super.emitBlockQuads(emitter, blockView, state, pos, randomSupplier, cullTest); return; } ModelObjectsContainer container = ModelObjectsContainer.get(); if (!container.featureStates.getConnectedTexturesState().isEnabled()) { - super.emitBlockQuads(blockView, state, pos, randomSupplier, context); + super.emitBlockQuads(emitter, blockView, state, pos, randomSupplier, cullTest); return; } CtmQuadTransform quadTransform = container.ctmQuadTransform; if (quadTransform.isActive()) { - super.emitBlockQuads(blockView, state, pos, randomSupplier, context); + super.emitBlockQuads(emitter, blockView, state, pos, randomSupplier, cullTest); return; } @@ -65,13 +69,13 @@ public void emitBlockQuads(BlockRenderView blockView, BlockState state, BlockPos // especially if there is an actual use case for it. BlockState appearanceState = state.getAppearance(blockView, pos, Direction.DOWN, state, pos); - quadTransform.prepare(blockView, appearanceState, state, pos, randomSupplier, context, ContinuityConfig.INSTANCE.useManualCulling.get(), getSliceFunc(appearanceState)); + quadTransform.prepare(blockView, appearanceState, state, pos, randomSupplier, cullTest, getSliceFunc(appearanceState)); - context.pushTransform(quadTransform); - super.emitBlockQuads(blockView, state, pos, randomSupplier, context); - context.popTransform(); + emitter.pushTransform(quadTransform); + super.emitBlockQuads(emitter, blockView, state, pos, randomSupplier, cullTest); + emitter.popTransform(); - quadTransform.processingContext.outputTo(context.getEmitter()); + quadTransform.processingContext.outputTo(emitter); quadTransform.reset(); } @@ -100,7 +104,7 @@ protected Function getSliceFunc(BlockState state) return QuadProcessors.getCache(state); } - protected static class CtmQuadTransform implements RenderContext.QuadTransform { + protected static class CtmQuadTransform implements QuadTransform { protected final ProcessingContextImpl processingContext = new ProcessingContextImpl(); protected BlockRenderView blockView; @@ -108,15 +112,14 @@ protected static class CtmQuadTransform implements RenderContext.QuadTransform { protected BlockState state; protected BlockPos pos; protected Supplier randomSupplier; - protected RenderContext renderContext; - protected boolean useManualCulling; + protected Predicate<@Nullable Direction> cullTest; protected Function sliceFunc; protected boolean active; @Override public boolean transform(MutableQuadView quad) { - if (useManualCulling && renderContext.isFaceCulled(quad.cullFace())) { + if (cullTest.test(quad.cullFace())) { return false; } @@ -156,19 +159,16 @@ public boolean isActive() { return active; } - public void prepare(BlockRenderView blockView, BlockState appearanceState, BlockState state, BlockPos pos, Supplier randomSupplier, RenderContext renderContext, boolean useManualCulling, Function sliceFunc) { + public void prepare(BlockRenderView blockView, BlockState appearanceState, BlockState state, BlockPos pos, Supplier randomSupplier, Predicate<@Nullable Direction> cullTest, Function sliceFunc) { this.blockView = blockView; this.appearanceState = appearanceState; this.state = state; this.pos = pos; this.randomSupplier = randomSupplier; - this.renderContext = renderContext; - this.useManualCulling = useManualCulling; + this.cullTest = cullTest; this.sliceFunc = sliceFunc; active = true; - - processingContext.prepare(); } public void reset() { @@ -177,8 +177,7 @@ public void reset() { state = null; pos = null; randomSupplier = null; - renderContext = null; - useManualCulling = false; + cullTest = null; sliceFunc = null; active = false; diff --git a/src/main/java/me/pepperbell/continuity/client/model/EmissiveBakedModel.java b/src/main/java/me/pepperbell/continuity/client/model/EmissiveBakedModel.java index f42e2eb8..6254ea11 100644 --- a/src/main/java/me/pepperbell/continuity/client/model/EmissiveBakedModel.java +++ b/src/main/java/me/pepperbell/continuity/client/model/EmissiveBakedModel.java @@ -1,7 +1,10 @@ package me.pepperbell.continuity.client.model; +import java.util.function.Predicate; import java.util.function.Supplier; +import org.jetbrains.annotations.Nullable; + import me.pepperbell.continuity.api.client.EmissiveSpriteApi; import me.pepperbell.continuity.client.config.ContinuityConfig; import me.pepperbell.continuity.client.util.QuadUtil; @@ -9,23 +12,23 @@ import net.fabricmc.fabric.api.renderer.v1.material.BlendMode; import net.fabricmc.fabric.api.renderer.v1.material.MaterialFinder; import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial; -import net.fabricmc.fabric.api.renderer.v1.mesh.MeshBuilder; +import net.fabricmc.fabric.api.renderer.v1.mesh.MutableMesh; import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView; import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter; -import net.fabricmc.fabric.api.renderer.v1.model.ForwardingBakedModel; -import net.fabricmc.fabric.api.renderer.v1.render.RenderContext; +import net.fabricmc.fabric.api.renderer.v1.mesh.QuadTransform; import net.fabricmc.fabric.api.util.TriState; import net.minecraft.block.BlockState; import net.minecraft.client.render.RenderLayer; import net.minecraft.client.render.RenderLayers; import net.minecraft.client.render.model.BakedModel; +import net.minecraft.client.render.model.WrapperBakedModel; import net.minecraft.client.texture.Sprite; -import net.minecraft.item.ItemStack; import net.minecraft.util.math.BlockPos; +import net.minecraft.util.math.Direction; import net.minecraft.util.math.random.Random; import net.minecraft.world.BlockRenderView; -public class EmissiveBakedModel extends ForwardingBakedModel { +public class EmissiveBakedModel extends WrapperBakedModel { protected static final RenderMaterial[] EMISSIVE_MATERIALS; protected static final RenderMaterial DEFAULT_EMISSIVE_MATERIAL; protected static final RenderMaterial CUTOUT_MIPPED_EMISSIVE_MATERIAL; @@ -43,70 +46,68 @@ public class EmissiveBakedModel extends ForwardingBakedModel { } public EmissiveBakedModel(BakedModel wrapped) { - this.wrapped = wrapped; + super(wrapped); } @Override - public void emitBlockQuads(BlockRenderView blockView, BlockState state, BlockPos pos, Supplier randomSupplier, RenderContext context) { + public void emitBlockQuads(QuadEmitter emitter, BlockRenderView blockView, BlockState state, BlockPos pos, Supplier randomSupplier, Predicate<@Nullable Direction> cullTest) { if (!ContinuityConfig.INSTANCE.emissiveTextures.get()) { - super.emitBlockQuads(blockView, state, pos, randomSupplier, context); + super.emitBlockQuads(emitter, blockView, state, pos, randomSupplier, cullTest); return; } ModelObjectsContainer container = ModelObjectsContainer.get(); if (!container.featureStates.getEmissiveTexturesState().isEnabled()) { - super.emitBlockQuads(blockView, state, pos, randomSupplier, context); + super.emitBlockQuads(emitter, blockView, state, pos, randomSupplier, cullTest); return; } EmissiveBlockQuadTransform quadTransform = container.emissiveBlockQuadTransform; if (quadTransform.isActive()) { - super.emitBlockQuads(blockView, state, pos, randomSupplier, context); + super.emitBlockQuads(emitter, blockView, state, pos, randomSupplier, cullTest); return; } - MeshBuilder meshBuilder = container.meshBuilder; - quadTransform.prepare(meshBuilder.getEmitter(), blockView, state, pos, context, ContinuityConfig.INSTANCE.useManualCulling.get()); + MutableMesh mutableMesh = container.mutableMesh; + quadTransform.prepare(mutableMesh.emitter(), state, cullTest); - context.pushTransform(quadTransform); - super.emitBlockQuads(blockView, state, pos, randomSupplier, context); - context.popTransform(); + emitter.pushTransform(quadTransform); + super.emitBlockQuads(emitter, blockView, state, pos, randomSupplier, cullTest); + emitter.popTransform(); - if (quadTransform.didEmit()) { - meshBuilder.build().outputTo(context.getEmitter()); - } + mutableMesh.outputTo(emitter); + mutableMesh.clear(); quadTransform.reset(); } @Override - public void emitItemQuads(ItemStack stack, Supplier randomSupplier, RenderContext context) { + public void emitItemQuads(QuadEmitter emitter, Supplier randomSupplier) { if (!ContinuityConfig.INSTANCE.emissiveTextures.get()) { - super.emitItemQuads(stack, randomSupplier, context); + super.emitItemQuads(emitter, randomSupplier); return; } ModelObjectsContainer container = ModelObjectsContainer.get(); if (!container.featureStates.getEmissiveTexturesState().isEnabled()) { - super.emitItemQuads(stack, randomSupplier, context); + super.emitItemQuads(emitter, randomSupplier); return; } EmissiveItemQuadTransform quadTransform = container.emissiveItemQuadTransform; if (quadTransform.isActive()) { - super.emitItemQuads(stack, randomSupplier, context); + super.emitItemQuads(emitter, randomSupplier); return; } - MeshBuilder meshBuilder = container.meshBuilder; - quadTransform.prepare(meshBuilder.getEmitter()); + MutableMesh mutableMesh = container.mutableMesh; + quadTransform.prepare(mutableMesh.emitter()); - context.pushTransform(quadTransform); - super.emitItemQuads(stack, randomSupplier, context); - context.popTransform(); + emitter.pushTransform(quadTransform); + super.emitItemQuads(emitter, randomSupplier); + emitter.popTransform(); - if (quadTransform.didEmit()) { - meshBuilder.build().outputTo(context.getEmitter()); - } + mutableMesh.outputTo(emitter); + mutableMesh.clear(); quadTransform.reset(); } @@ -118,22 +119,18 @@ public boolean isVanillaAdapter() { return false; } - protected static class EmissiveBlockQuadTransform implements RenderContext.QuadTransform { + protected static class EmissiveBlockQuadTransform implements QuadTransform { protected QuadEmitter emitter; - protected BlockRenderView blockView; protected BlockState state; - protected BlockPos pos; - protected RenderContext renderContext; - protected boolean useManualCulling; + protected Predicate<@Nullable Direction> cullTest; protected boolean active; - protected boolean didEmit; protected boolean calculateDefaultLayer; protected boolean isDefaultLayerSolid; @Override public boolean transform(MutableQuadView quad) { - if (useManualCulling && renderContext.isFaceCulled(quad.cullFace())) { + if (cullTest.test(quad.cullFace())) { return false; } @@ -164,7 +161,6 @@ public boolean transform(MutableQuadView quad) { emitter.material(emissiveMaterial); QuadUtil.interpolate(emitter, sprite, emissiveSprite); emitter.emit(); - didEmit = true; } return true; } @@ -173,41 +169,29 @@ public boolean isActive() { return active; } - public boolean didEmit() { - return didEmit; - } - - public void prepare(QuadEmitter emitter, BlockRenderView blockView, BlockState state, BlockPos pos, RenderContext renderContext, boolean useManualCulling) { + public void prepare(QuadEmitter emitter, BlockState state, Predicate<@Nullable Direction> cullTest) { this.emitter = emitter; - this.blockView = blockView; this.state = state; - this.pos = pos; - this.renderContext = renderContext; - this.useManualCulling = useManualCulling; + this.cullTest = cullTest; active = true; - didEmit = false; calculateDefaultLayer = true; isDefaultLayerSolid = false; } public void reset() { emitter = null; - blockView = null; state = null; - pos = null; - renderContext = null; - useManualCulling = false; + cullTest = null; active = false; } } - protected static class EmissiveItemQuadTransform implements RenderContext.QuadTransform { + protected static class EmissiveItemQuadTransform implements QuadTransform { protected QuadEmitter emitter; protected boolean active; - protected boolean didEmit; @Override public boolean transform(MutableQuadView quad) { @@ -218,7 +202,6 @@ public boolean transform(MutableQuadView quad) { emitter.material(DEFAULT_EMISSIVE_MATERIAL); QuadUtil.interpolate(emitter, sprite, emissiveSprite); emitter.emit(); - didEmit = true; } return true; } @@ -227,20 +210,16 @@ public boolean isActive() { return active; } - public boolean didEmit() { - return didEmit; - } - public void prepare(QuadEmitter emitter) { this.emitter = emitter; active = true; - didEmit = false; } public void reset() { - active = false; emitter = null; + + active = false; } } } diff --git a/src/main/java/me/pepperbell/continuity/client/model/ModelObjectsContainer.java b/src/main/java/me/pepperbell/continuity/client/model/ModelObjectsContainer.java index eb0936ec..b61a66b0 100644 --- a/src/main/java/me/pepperbell/continuity/client/model/ModelObjectsContainer.java +++ b/src/main/java/me/pepperbell/continuity/client/model/ModelObjectsContainer.java @@ -1,8 +1,8 @@ package me.pepperbell.continuity.client.model; import me.pepperbell.continuity.impl.client.ContinuityFeatureStatesImpl; -import net.fabricmc.fabric.api.renderer.v1.RendererAccess; -import net.fabricmc.fabric.api.renderer.v1.mesh.MeshBuilder; +import net.fabricmc.fabric.api.renderer.v1.Renderer; +import net.fabricmc.fabric.api.renderer.v1.mesh.MutableMesh; public class ModelObjectsContainer { public static final ThreadLocal THREAD_LOCAL = ThreadLocal.withInitial(ModelObjectsContainer::new); @@ -12,7 +12,7 @@ public class ModelObjectsContainer { public final EmissiveBakedModel.EmissiveItemQuadTransform emissiveItemQuadTransform = new EmissiveBakedModel.EmissiveItemQuadTransform(); public final ContinuityFeatureStatesImpl featureStates = new ContinuityFeatureStatesImpl(); - public final MeshBuilder meshBuilder = RendererAccess.INSTANCE.getRenderer().meshBuilder(); + public final MutableMesh mutableMesh = Renderer.get().mutableMesh(); public static ModelObjectsContainer get() { return THREAD_LOCAL.get(); diff --git a/src/main/java/me/pepperbell/continuity/client/processor/CompactCtmQuadProcessor.java b/src/main/java/me/pepperbell/continuity/client/processor/CompactCtmQuadProcessor.java index 04268f04..6b0bf753 100644 --- a/src/main/java/me/pepperbell/continuity/client/processor/CompactCtmQuadProcessor.java +++ b/src/main/java/me/pepperbell/continuity/client/processor/CompactCtmQuadProcessor.java @@ -342,7 +342,6 @@ public ProcessingResult processQuadInner(MutableQuadView quad, Sprite sprite, Bl } } - context.markHasExtraQuads(); return ProcessingResult.DISCARD; } else if (uSplit | vSplit) { boolean firstSplit; @@ -421,7 +420,6 @@ public ProcessingResult processQuadInner(MutableQuadView quad, Sprite sprite, Bl splitHalf(quad, sprite, vertexContainer, 2, extraQuadEmitter, spriteIndexB); } - context.markHasExtraQuads(); return ProcessingResult.DISCARD; } else { int quadrant; diff --git a/src/main/java/me/pepperbell/continuity/client/processor/ProcessingDataKeys.java b/src/main/java/me/pepperbell/continuity/client/processor/ProcessingDataKeys.java index 985843c2..954da5d0 100644 --- a/src/main/java/me/pepperbell/continuity/client/processor/ProcessingDataKeys.java +++ b/src/main/java/me/pepperbell/continuity/client/processor/ProcessingDataKeys.java @@ -6,7 +6,6 @@ import me.pepperbell.continuity.api.client.ProcessingDataKey; import me.pepperbell.continuity.api.client.ProcessingDataKeyRegistry; import me.pepperbell.continuity.client.ContinuityClient; -import me.pepperbell.continuity.client.processor.overlay.SimpleOverlayQuadProcessor; import me.pepperbell.continuity.client.processor.overlay.StandardOverlayQuadProcessor; import net.minecraft.util.math.BlockPos; @@ -15,8 +14,7 @@ public final class ProcessingDataKeys { public static final ProcessingDataKey BIOME_CACHE = create("biome_cache", BaseProcessingPredicate.BiomeCache::new, BaseProcessingPredicate.BiomeCache::reset); public static final ProcessingDataKey BLOCK_ENTITY_NAME_CACHE = create("block_entity_name_cache", BaseProcessingPredicate.BlockEntityNameCache::new, BaseProcessingPredicate.BlockEntityNameCache::reset); public static final ProcessingDataKey VERTEX_CONTAINER = create("vertex_container", CompactCtmQuadProcessor.VertexContainer::new); - public static final ProcessingDataKey STANDARD_OVERLAY_EMITTER_POOL = create("standard_overlay_emitter_pool", StandardOverlayQuadProcessor.OverlayEmitterPool::new, StandardOverlayQuadProcessor.OverlayEmitterPool::reset); - public static final ProcessingDataKey SIMPLE_OVERLAY_EMITTER_POOL = create("simple_overlay_emitter_pool", SimpleOverlayQuadProcessor.OverlayEmitterPool::new, SimpleOverlayQuadProcessor.OverlayEmitterPool::reset); + public static final ProcessingDataKey SPRITE_COLLECTOR = create("sprite_collector", StandardOverlayQuadProcessor.SpriteCollector::new); private static ProcessingDataKey create(String id, Supplier valueSupplier) { return ProcessingDataKeyRegistry.get().registerKey(ContinuityClient.asId(id), valueSupplier); diff --git a/src/main/java/me/pepperbell/continuity/client/processor/overlay/SimpleOverlayQuadProcessor.java b/src/main/java/me/pepperbell/continuity/client/processor/overlay/SimpleOverlayQuadProcessor.java index ac48553f..4b263180 100644 --- a/src/main/java/me/pepperbell/continuity/client/processor/overlay/SimpleOverlayQuadProcessor.java +++ b/src/main/java/me/pepperbell/continuity/client/processor/overlay/SimpleOverlayQuadProcessor.java @@ -1,14 +1,10 @@ package me.pepperbell.continuity.client.processor.overlay; -import java.util.List; -import java.util.function.Consumer; import java.util.function.Supplier; import org.jetbrains.annotations.Nullable; -import it.unimi.dsi.fastutil.objects.ObjectArrayList; import me.pepperbell.continuity.api.client.QuadProcessor; -import me.pepperbell.continuity.client.processor.ProcessingDataKeys; import me.pepperbell.continuity.client.processor.ProcessingPredicate; import me.pepperbell.continuity.client.processor.simple.SimpleQuadProcessor; import me.pepperbell.continuity.client.processor.simple.SpriteProvider; @@ -20,11 +16,9 @@ import net.fabricmc.fabric.api.renderer.v1.material.BlendMode; import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial; import net.fabricmc.fabric.api.renderer.v1.mesh.MutableQuadView; -import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter; import net.minecraft.block.BlockState; import net.minecraft.client.texture.Sprite; import net.minecraft.util.math.BlockPos; -import net.minecraft.util.math.Direction; import net.minecraft.util.math.random.Random; import net.minecraft.world.BlockRenderView; @@ -46,51 +40,12 @@ public ProcessingResult processQuad(MutableQuadView quad, Sprite sprite, BlockRe if (processingPredicate.shouldProcessQuad(quad, sprite, blockView, appearanceState, state, pos, context)) { Sprite newSprite = spriteProvider.getSprite(quad, sprite, blockView, appearanceState, state, pos, randomSupplier, context); if (newSprite != null && !TextureUtil.isMissingSprite(newSprite)) { - OverlayEmitter emitter = context.getData(ProcessingDataKeys.SIMPLE_OVERLAY_EMITTER_POOL).get(); - emitter.prepare(quad.lightFace(), newSprite, RenderUtil.getTintColor(tintBlock, blockView, pos, tintIndex), material); - context.addEmitterConsumer(emitter); + QuadUtil.emitOverlayQuad(context.getExtraQuadEmitter(), quad.lightFace(), newSprite, RenderUtil.getTintColor(tintBlock, blockView, pos, tintIndex), material); } } return ProcessingResult.NEXT_PROCESSOR; } - public static class OverlayEmitter implements Consumer { - protected Direction face; - protected Sprite sprite; - protected int color; - protected RenderMaterial material; - - @Override - public void accept(QuadEmitter emitter) { - QuadUtil.emitOverlayQuad(emitter, face, sprite, color, material); - } - - public void prepare(Direction face, Sprite sprite, int color, RenderMaterial material) { - this.face = face; - this.sprite = sprite; - this.color = color; - this.material = material; - } - } - - public static class OverlayEmitterPool { - protected final List list = new ObjectArrayList<>(); - protected int nextIndex = 0; - - public OverlayEmitter get() { - if (nextIndex >= list.size()) { - list.add(new OverlayEmitter()); - } - OverlayEmitter emitter = list.get(nextIndex); - nextIndex++; - return emitter; - } - - public void reset() { - nextIndex = 0; - } - } - public static class Factory extends SimpleQuadProcessor.Factory { public Factory(SpriteProvider.Factory spriteProviderFactory) { super(spriteProviderFactory); diff --git a/src/main/java/me/pepperbell/continuity/client/processor/overlay/StandardOverlayQuadProcessor.java b/src/main/java/me/pepperbell/continuity/client/processor/overlay/StandardOverlayQuadProcessor.java index 90eb5867..e8feac33 100644 --- a/src/main/java/me/pepperbell/continuity/client/processor/overlay/StandardOverlayQuadProcessor.java +++ b/src/main/java/me/pepperbell/continuity/client/processor/overlay/StandardOverlayQuadProcessor.java @@ -1,14 +1,11 @@ package me.pepperbell.continuity.client.processor.overlay; -import java.util.List; import java.util.Set; -import java.util.function.Consumer; import java.util.function.Predicate; import java.util.function.Supplier; import org.jetbrains.annotations.Nullable; -import it.unimi.dsi.fastutil.objects.ObjectArrayList; import me.pepperbell.continuity.api.client.ProcessingDataProvider; import me.pepperbell.continuity.api.client.QuadProcessor; import me.pepperbell.continuity.client.processor.AbstractQuadProcessor; @@ -76,9 +73,14 @@ public StandardOverlayQuadProcessor(Sprite[] sprites, ProcessingPredicate proces @Override public ProcessingResult processQuadInner(MutableQuadView quad, Sprite sprite, BlockRenderView blockView, BlockState appearanceState, BlockState state, BlockPos pos, Supplier randomSupplier, int pass, ProcessingContext context) { Direction lightFace = quad.lightFace(); - OverlayEmitter emitter = getEmitter(blockView, appearanceState, state, pos, lightFace, sprite, DirectionMaps.getMap(lightFace)[0], context); - if (emitter != null) { - context.addEmitterConsumer(emitter); + SpriteCollector collector = getSprites(blockView, appearanceState, state, pos, lightFace, sprite, DirectionMaps.getMap(lightFace)[0], context); + if (collector != null) { + QuadEmitter emitter = context.getExtraQuadEmitter(); + int tintColor = RenderUtil.getTintColor(tintBlock, blockView, pos, tintIndex); + for (int i = 0; i < collector.spriteAmount; i++) { + QuadUtil.emitOverlayQuad(emitter, lightFace, collector.sprites[i], tintColor, material); + } + collector.clear(); } return ProcessingResult.NEXT_PROCESSOR; } @@ -131,21 +133,20 @@ protected boolean appliesOverlayCorner(Direction dir0, Direction dir1, BlockPos. return false; } - protected OverlayEmitter fromTwoSidesAdj(OverlayEmitter emitter, @Nullable BlockState appearanceState0, @Nullable BlockState appearanceState1, Direction dir0, Direction dir1, int sprite, int spriteC01, BlockPos.Mutable mutablePos, BlockRenderView blockView, BlockState appearanceState, BlockState state, BlockPos pos, Direction lightFace, Sprite quadSprite) { - prepareEmitter(emitter, lightFace, blockView, pos); - emitter.addSprite(sprites[sprite]); + protected SpriteCollector fromTwoSidesAdj(SpriteCollector collector, @Nullable BlockState appearanceState0, @Nullable BlockState appearanceState1, Direction dir0, Direction dir1, int sprite, int spriteC01, BlockPos.Mutable mutablePos, BlockRenderView blockView, BlockState appearanceState, BlockState state, BlockPos pos, Direction lightFace, Sprite quadSprite) { + collector.add(sprites[sprite]); // OptiFine does not check whether the other two adjacent blocks have the same overlay before trying to apply // the corner overlay. I consider this a bug since it is inconsistent with other cases, so it is fixed here by // checking those blocks. if ((hasSameOverlay(appearanceState0, lightFace) || hasSameOverlay(appearanceState1, lightFace)) && appliesOverlayCorner(dir0, dir1, mutablePos, blockView, appearanceState, state, pos, lightFace, quadSprite)) { - emitter.addSprite(sprites[spriteC01]); + collector.add(sprites[spriteC01]); } - return emitter; + return collector; } - protected OverlayEmitter fromOneSide(OverlayEmitter emitter, @Nullable BlockState appearanceState0, @Nullable BlockState appearanceState1, @Nullable BlockState appearanceState2, Direction dir0, Direction dir1, Direction dir2, int sprite, int spriteC01, int spriteC12, BlockPos.Mutable mutablePos, BlockRenderView blockView, BlockState appearanceState, BlockState state, BlockPos pos, Direction lightFace, Sprite quadSprite) { + protected SpriteCollector fromOneSide(SpriteCollector collector, @Nullable BlockState appearanceState0, @Nullable BlockState appearanceState1, @Nullable BlockState appearanceState2, Direction dir0, Direction dir1, Direction dir2, int sprite, int spriteC01, int spriteC12, BlockPos.Mutable mutablePos, BlockRenderView blockView, BlockState appearanceState, BlockState state, BlockPos pos, Direction lightFace, Sprite quadSprite) { boolean c01; boolean c12; if (hasSameOverlay(appearanceState1, lightFace)) { @@ -156,36 +157,29 @@ protected OverlayEmitter fromOneSide(OverlayEmitter emitter, @Nullable BlockStat c12 = hasSameOverlay(appearanceState2, lightFace); } - prepareEmitter(emitter, lightFace, blockView, pos); - emitter.addSprite(sprites[sprite]); + collector.add(sprites[sprite]); if (c01 && appliesOverlayCorner(dir0, dir1, mutablePos, blockView, appearanceState, state, pos, lightFace, quadSprite)) { - emitter.addSprite(sprites[spriteC01]); + collector.add(sprites[spriteC01]); } if (c12 && appliesOverlayCorner(dir1, dir2, mutablePos, blockView, appearanceState, state, pos, lightFace, quadSprite)) { - emitter.addSprite(sprites[spriteC12]); + collector.add(sprites[spriteC12]); } - return emitter; - } - - protected static OverlayEmitter getEmitter(ProcessingDataProvider dataProvider) { - return dataProvider.getData(ProcessingDataKeys.STANDARD_OVERLAY_EMITTER_POOL).get(); + return collector; } - protected void prepareEmitter(OverlayEmitter emitter, Direction face, BlockRenderView blockView, BlockPos pos) { - emitter.prepare(face, RenderUtil.getTintColor(tintBlock, blockView, pos, tintIndex), material); + protected static SpriteCollector getCollector(ProcessingDataProvider dataProvider) { + return dataProvider.getData(ProcessingDataKeys.SPRITE_COLLECTOR); } - protected OverlayEmitter prepareEmitter(OverlayEmitter emitter, Direction face, BlockRenderView blockView, BlockPos pos, int sprite0) { - prepareEmitter(emitter, face, blockView, pos); - emitter.addSprite(sprites[sprite0]); - return emitter; + protected SpriteCollector prepareCollector(SpriteCollector collector, int sprite0) { + collector.add(sprites[sprite0]); + return collector; } - protected OverlayEmitter prepareEmitter(OverlayEmitter emitter, Direction face, BlockRenderView blockView, BlockPos pos, int sprite0, int sprite1) { - prepareEmitter(emitter, face, blockView, pos); - emitter.addSprite(sprites[sprite0]); - emitter.addSprite(sprites[sprite1]); - return emitter; + protected SpriteCollector prepareCollector(SpriteCollector collector, int sprite0, int sprite1) { + collector.add(sprites[sprite0]); + collector.add(sprites[sprite1]); + return collector; } /* @@ -208,7 +202,7 @@ protected OverlayEmitter prepareEmitter(OverlayEmitter emitter, Direction face, 16: CORNER L+U */ @Nullable - protected OverlayEmitter getEmitter(BlockRenderView blockView, BlockState appearanceState, BlockState state, BlockPos pos, Direction lightFace, Sprite quadSprite, Direction[] directions, ProcessingDataProvider dataProvider) { + protected SpriteCollector getSprites(BlockRenderView blockView, BlockState appearanceState, BlockState state, BlockPos pos, Direction lightFace, Sprite quadSprite, Direction[] directions, ProcessingDataProvider dataProvider) { BlockPos.Mutable mutablePos = dataProvider.getData(ProcessingDataKeys.MUTABLE_POS); // [up] | [right] | [down] | [left] @@ -270,24 +264,24 @@ protected OverlayEmitter getEmitter(BlockRenderView blockView, BlockState appear } return switch (applications) { - case 0b1111 -> prepareEmitter(getEmitter(dataProvider), lightFace, blockView, pos, 8); - case 0b0111 -> prepareEmitter(getEmitter(dataProvider), lightFace, blockView, pos, 5); - case 0b1011 -> prepareEmitter(getEmitter(dataProvider), lightFace, blockView, pos, 6); - case 0b1101 -> prepareEmitter(getEmitter(dataProvider), lightFace, blockView, pos, 13); - case 0b1110 -> prepareEmitter(getEmitter(dataProvider), lightFace, blockView, pos, 12); + case 0b1111 -> prepareCollector(getCollector(dataProvider), 8); + case 0b0111 -> prepareCollector(getCollector(dataProvider), 5); + case 0b1011 -> prepareCollector(getCollector(dataProvider), 6); + case 0b1101 -> prepareCollector(getCollector(dataProvider), 13); + case 0b1110 -> prepareCollector(getCollector(dataProvider), 12); // - case 0b0101 -> prepareEmitter(getEmitter(dataProvider), lightFace, blockView, pos, 9, 7); - case 0b1010 -> prepareEmitter(getEmitter(dataProvider), lightFace, blockView, pos, 1, 15); + case 0b0101 -> prepareCollector(getCollector(dataProvider), 9, 7); + case 0b1010 -> prepareCollector(getCollector(dataProvider), 1, 15); // - case 0b0011 -> fromTwoSidesAdj(getEmitter(dataProvider), appearanceState2, appearanceState3, directions[2], directions[3], 4, 14, mutablePos, blockView, appearanceState, state, pos, lightFace, quadSprite); - case 0b0110 -> fromTwoSidesAdj(getEmitter(dataProvider), appearanceState3, appearanceState0, directions[3], directions[0], 3, 16, mutablePos, blockView, appearanceState, state, pos, lightFace, quadSprite); - case 0b1100 -> fromTwoSidesAdj(getEmitter(dataProvider), appearanceState0, appearanceState1, directions[0], directions[1], 10, 2, mutablePos, blockView, appearanceState, state, pos, lightFace, quadSprite); - case 0b1001 -> fromTwoSidesAdj(getEmitter(dataProvider), appearanceState1, appearanceState2, directions[1], directions[2], 11, 0, mutablePos, blockView, appearanceState, state, pos, lightFace, quadSprite); + case 0b0011 -> fromTwoSidesAdj(getCollector(dataProvider), appearanceState2, appearanceState3, directions[2], directions[3], 4, 14, mutablePos, blockView, appearanceState, state, pos, lightFace, quadSprite); + case 0b0110 -> fromTwoSidesAdj(getCollector(dataProvider), appearanceState3, appearanceState0, directions[3], directions[0], 3, 16, mutablePos, blockView, appearanceState, state, pos, lightFace, quadSprite); + case 0b1100 -> fromTwoSidesAdj(getCollector(dataProvider), appearanceState0, appearanceState1, directions[0], directions[1], 10, 2, mutablePos, blockView, appearanceState, state, pos, lightFace, quadSprite); + case 0b1001 -> fromTwoSidesAdj(getCollector(dataProvider), appearanceState1, appearanceState2, directions[1], directions[2], 11, 0, mutablePos, blockView, appearanceState, state, pos, lightFace, quadSprite); // - case 0b0001 -> fromOneSide(getEmitter(dataProvider), appearanceState1, appearanceState2, appearanceState3, directions[1], directions[2], directions[3], 9, 0, 14, mutablePos, blockView, appearanceState, state, pos, lightFace, quadSprite); - case 0b0010 -> fromOneSide(getEmitter(dataProvider), appearanceState2, appearanceState3, appearanceState0, directions[2], directions[3], directions[0], 1, 14, 16, mutablePos, blockView, appearanceState, state, pos, lightFace, quadSprite); - case 0b0100 -> fromOneSide(getEmitter(dataProvider), appearanceState3, appearanceState0, appearanceState1, directions[3], directions[0], directions[1], 7, 16, 2, mutablePos, blockView, appearanceState, state, pos, lightFace, quadSprite); - case 0b1000 -> fromOneSide(getEmitter(dataProvider), appearanceState0, appearanceState1, appearanceState2, directions[0], directions[1], directions[2], 15, 2, 0, mutablePos, blockView, appearanceState, state, pos, lightFace, quadSprite); + case 0b0001 -> fromOneSide(getCollector(dataProvider), appearanceState1, appearanceState2, appearanceState3, directions[1], directions[2], directions[3], 9, 0, 14, mutablePos, blockView, appearanceState, state, pos, lightFace, quadSprite); + case 0b0010 -> fromOneSide(getCollector(dataProvider), appearanceState2, appearanceState3, appearanceState0, directions[2], directions[3], directions[0], 1, 14, 16, mutablePos, blockView, appearanceState, state, pos, lightFace, quadSprite); + case 0b0100 -> fromOneSide(getCollector(dataProvider), appearanceState3, appearanceState0, appearanceState1, directions[3], directions[0], directions[1], 7, 16, 2, mutablePos, blockView, appearanceState, state, pos, lightFace, quadSprite); + case 0b1000 -> fromOneSide(getCollector(dataProvider), appearanceState0, appearanceState1, appearanceState2, directions[0], directions[1], directions[2], 15, 2, 0, mutablePos, blockView, appearanceState, state, pos, lightFace, quadSprite); // case 0b0000 -> { boolean s0 = hasSameOverlay(appearanceState0, lightFace); @@ -301,21 +295,20 @@ protected OverlayEmitter getEmitter(BlockRenderView blockView, BlockState appear boolean c30 = (s3 | s0) && appliesOverlayCorner(directions[3], directions[0], mutablePos, blockView, appearanceState, state, pos, lightFace, quadSprite); if (c01 | c12 | c23 | c30) { - OverlayEmitter emitter = getEmitter(dataProvider); - prepareEmitter(emitter, lightFace, blockView, pos); + SpriteCollector collector = getCollector(dataProvider); if (c01) { - emitter.addSprite(sprites[2]); + collector.add(sprites[2]); } if (c12) { - emitter.addSprite(sprites[0]); + collector.add(sprites[0]); } if (c23) { - emitter.addSprite(sprites[14]); + collector.add(sprites[14]); } if (c30) { - emitter.addSprite(sprites[16]); + collector.add(sprites[16]); } - yield emitter; + yield collector; } yield null; @@ -325,52 +318,21 @@ protected OverlayEmitter getEmitter(BlockRenderView blockView, BlockState appear }; } - public static class OverlayEmitter implements Consumer { + public static class SpriteCollector { protected static final Sprite[] EMPTY_SPRITES = new Sprite[4]; protected Sprite[] sprites = new Sprite[4]; protected int spriteAmount; - protected Direction face; - protected int color; - protected RenderMaterial material; - - @Override - public void accept(QuadEmitter emitter) { - for (int i = 0; i < spriteAmount; i++) { - QuadUtil.emitOverlayQuad(emitter, face, sprites[i], color, material); - } - } - - public void prepare(Direction face, int color, RenderMaterial material) { - System.arraycopy(EMPTY_SPRITES, 0, sprites, 0, EMPTY_SPRITES.length); - spriteAmount = 0; - this.face = face; - this.color = color; - this.material = material; - } - public void addSprite(@Nullable Sprite sprite) { + public void add(@Nullable Sprite sprite) { if (sprite != null) { sprites[spriteAmount++] = sprite; } } - } - public static class OverlayEmitterPool { - protected final List list = new ObjectArrayList<>(); - protected int nextIndex = 0; - - public OverlayEmitter get() { - if (nextIndex >= list.size()) { - list.add(new OverlayEmitter()); - } - OverlayEmitter emitter = list.get(nextIndex); - nextIndex++; - return emitter; - } - - public void reset() { - nextIndex = 0; + public void clear() { + System.arraycopy(EMPTY_SPRITES, 0, sprites, 0, EMPTY_SPRITES.length); + spriteAmount = 0; } } diff --git a/src/main/java/me/pepperbell/continuity/client/resource/BakedModelManagerBakeContext.java b/src/main/java/me/pepperbell/continuity/client/resource/BakedModelManagerBakeContext.java new file mode 100644 index 00000000..97d4676b --- /dev/null +++ b/src/main/java/me/pepperbell/continuity/client/resource/BakedModelManagerBakeContext.java @@ -0,0 +1,12 @@ +package me.pepperbell.continuity.client.resource; + +import java.util.Map; + +import net.minecraft.client.render.model.SpriteAtlasManager; +import net.minecraft.util.Identifier; + +public interface BakedModelManagerBakeContext { + ThreadLocal THREAD_LOCAL = new ThreadLocal<>(); + + void beforeBake(Map atlases); +} diff --git a/src/main/java/me/pepperbell/continuity/client/resource/BakedModelManagerReloadExtension.java b/src/main/java/me/pepperbell/continuity/client/resource/BakedModelManagerReloadExtension.java index 1c165b2f..7e95eb97 100644 --- a/src/main/java/me/pepperbell/continuity/client/resource/BakedModelManagerReloadExtension.java +++ b/src/main/java/me/pepperbell/continuity/client/resource/BakedModelManagerReloadExtension.java @@ -17,7 +17,7 @@ import net.minecraft.resource.ResourceManager; import net.minecraft.util.Identifier; -public class BakedModelManagerReloadExtension { +public class BakedModelManagerReloadExtension implements BakedModelManagerBakeContext { private final CompletableFuture ctmLoadingResultFuture; private final AtomicBoolean wrapEmissiveModels = new AtomicBoolean(); private final SpriteLoaderLoadContextImpl spriteLoaderLoadContext; @@ -38,7 +38,8 @@ public void clearContext() { SpriteLoaderLoadContext.THREAD_LOCAL.set(null); } - public void beforeBaking(Map preparations) { + @Override + public void beforeBake(Map preparations) { CtmPropertiesLoader.LoadingResult result = ctmLoadingResultFuture.join(); List processorHolders = result.createProcessorHolders(spriteId -> { diff --git a/src/main/java/me/pepperbell/continuity/client/resource/ModelWrappingHandler.java b/src/main/java/me/pepperbell/continuity/client/resource/ModelWrappingHandler.java index 817dd86a..0e0dc62a 100644 --- a/src/main/java/me/pepperbell/continuity/client/resource/ModelWrappingHandler.java +++ b/src/main/java/me/pepperbell/continuity/client/resource/ModelWrappingHandler.java @@ -2,7 +2,6 @@ import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.Nullable; -import org.jetbrains.annotations.UnknownNullability; import com.google.common.collect.ImmutableMap; @@ -51,7 +50,7 @@ public static void resetInstance() { private static ImmutableMap createBlockStateModelIdMap() { ImmutableMap.Builder builder = ImmutableMap.builder(); - // Match code of BakedModelManager#bake + // Match code of BakedModelManager#toStateMap for (Block block : Registries.BLOCK) { Identifier blockId = block.getRegistryEntry().registryKey().getValue(); for (BlockState state : block.getStateManager().getStates()) { @@ -62,16 +61,8 @@ private static ImmutableMap createBlockStateModelId return builder.build(); } - public BakedModel wrap(@Nullable BakedModel model, @UnknownNullability Identifier resourceId, @UnknownNullability ModelIdentifier topLevelId) { - if (model != null && !model.isBuiltin() && (resourceId == null || !resourceId.equals(MissingModel.ID))) { - if (wrapCtm) { - if (topLevelId != null) { - BlockState state = blockStateModelIds.get(topLevelId); - if (state != null) { - model = new CtmBakedModel(model, state); - } - } - } + public BakedModel wrap(BakedModel model, Identifier id) { + if (!id.equals(MissingModel.ID)) { if (wrapEmissive) { model = new EmissiveBakedModel(model); } @@ -79,13 +70,40 @@ public BakedModel wrap(@Nullable BakedModel model, @UnknownNullability Identifie return model; } + public BakedModel wrapBlock(BakedModel model, ModelIdentifier topLevelId) { + if (wrapCtm) { + BlockState state = blockStateModelIds.get(topLevelId); + if (state != null) { + model = new CtmBakedModel(model, state); + } + } + if (wrapEmissive) { + model = new EmissiveBakedModel(model); + } + return model; + } + + public BakedModel ensureWrapped(BakedModel model) { + if (wrapEmissive && !(model instanceof EmissiveBakedModel)) { + return new EmissiveBakedModel(model); + } + return model; + } + @ApiStatus.Internal public static void init() { ModelLoadingPlugin.register(pluginCtx -> { pluginCtx.modifyModelAfterBake().register(ModelModifier.WRAP_LAST_PHASE, (model, ctx) -> { ModelWrappingHandler wrappingHandler = getInstance(); if (wrappingHandler != null) { - return wrappingHandler.wrap(model, ctx.resourceId(), ctx.topLevelId()); + return wrappingHandler.wrap(model, ctx.id()); + } + return model; + }); + pluginCtx.modifyBlockModelAfterBake().register(ModelModifier.WRAP_LAST_PHASE, (model, ctx) -> { + ModelWrappingHandler wrappingHandler = getInstance(); + if (wrappingHandler != null) { + return wrappingHandler.wrapBlock(model, ctx.id()); } return model; }); diff --git a/src/main/java/me/pepperbell/continuity/client/util/RenderUtil.java b/src/main/java/me/pepperbell/continuity/client/util/RenderUtil.java index 42a72b4c..5f3cf1c5 100644 --- a/src/main/java/me/pepperbell/continuity/client/util/RenderUtil.java +++ b/src/main/java/me/pepperbell/continuity/client/util/RenderUtil.java @@ -6,7 +6,7 @@ import org.jetbrains.annotations.Nullable; import me.pepperbell.continuity.client.ContinuityClient; -import net.fabricmc.fabric.api.renderer.v1.RendererAccess; +import net.fabricmc.fabric.api.renderer.v1.Renderer; import net.fabricmc.fabric.api.renderer.v1.material.BlendMode; import net.fabricmc.fabric.api.renderer.v1.material.MaterialFinder; import net.fabricmc.fabric.api.renderer.v1.material.RenderMaterial; @@ -30,7 +30,7 @@ public final class RenderUtil { private static final BlockColors BLOCK_COLORS = MinecraftClient.getInstance().getBlockColors(); private static final BakedModelManager MODEL_MANAGER = MinecraftClient.getInstance().getBakedModelManager(); - private static final ThreadLocal MATERIAL_FINDER = ThreadLocal.withInitial(() -> RendererAccess.INSTANCE.getRenderer().materialFinder()); + private static final ThreadLocal MATERIAL_FINDER = ThreadLocal.withInitial(() -> Renderer.get().materialFinder()); private static SpriteFinder blockAtlasSpriteFinder; diff --git a/src/main/java/me/pepperbell/continuity/impl/client/ProcessingContextImpl.java b/src/main/java/me/pepperbell/continuity/impl/client/ProcessingContextImpl.java index 94f30d40..8fcb5b60 100644 --- a/src/main/java/me/pepperbell/continuity/impl/client/ProcessingContextImpl.java +++ b/src/main/java/me/pepperbell/continuity/impl/client/ProcessingContextImpl.java @@ -1,45 +1,23 @@ package me.pepperbell.continuity.impl.client; import java.util.List; -import java.util.function.Consumer; import org.jetbrains.annotations.Nullable; -import it.unimi.dsi.fastutil.objects.ObjectArrayList; import me.pepperbell.continuity.api.client.ProcessingDataKey; import me.pepperbell.continuity.api.client.ProcessingDataKeyRegistry; import me.pepperbell.continuity.api.client.QuadProcessor; -import net.fabricmc.fabric.api.renderer.v1.RendererAccess; -import net.fabricmc.fabric.api.renderer.v1.mesh.Mesh; -import net.fabricmc.fabric.api.renderer.v1.mesh.MeshBuilder; +import net.fabricmc.fabric.api.renderer.v1.Renderer; +import net.fabricmc.fabric.api.renderer.v1.mesh.MutableMesh; import net.fabricmc.fabric.api.renderer.v1.mesh.QuadEmitter; public class ProcessingContextImpl implements QuadProcessor.ProcessingContext { - protected final List> emitterConsumers = new ObjectArrayList<>(); - protected final List meshes = new ObjectArrayList<>(); - protected final MeshBuilder meshBuilder = RendererAccess.INSTANCE.getRenderer().meshBuilder(); + protected final MutableMesh mutableMesh = Renderer.get().mutableMesh(); protected final Object[] processingData = new Object[ProcessingDataKeyRegistry.get().getRegisteredAmount()]; - protected boolean hasExtraQuads; - - @Override - public void addEmitterConsumer(Consumer consumer) { - emitterConsumers.add(consumer); - } - - @Override - public void addMesh(Mesh mesh) { - meshes.add(mesh); - } - @Override public QuadEmitter getExtraQuadEmitter() { - return meshBuilder.getEmitter(); - } - - @Override - public void markHasExtraQuads() { - hasExtraQuads = true; + return mutableMesh.emitter(); } @SuppressWarnings("unchecked") @@ -61,30 +39,11 @@ public T getDataOrNull(ProcessingDataKey key) { } public void outputTo(QuadEmitter emitter) { - if (!emitterConsumers.isEmpty()) { - int amount = emitterConsumers.size(); - for (int i = 0; i < amount; i++) { - emitterConsumers.get(i).accept(emitter); - } - } - if (!meshes.isEmpty()) { - int amount = meshes.size(); - for (int i = 0; i < amount; i++) { - meshes.get(i).outputTo(emitter); - } - } - if (hasExtraQuads) { - meshBuilder.build().outputTo(emitter); - } - } - - public void prepare() { - hasExtraQuads = false; + mutableMesh.outputTo(emitter); } public void reset() { - emitterConsumers.clear(); - meshes.clear(); + mutableMesh.clear(); resetData(); } diff --git a/src/main/resources/continuity.mixins.json b/src/main/resources/continuity.mixins.json index b55ccf34..ac9e89fe 100644 --- a/src/main/resources/continuity.mixins.json +++ b/src/main/resources/continuity.mixins.json @@ -8,6 +8,7 @@ "BakedModelManagerMixin", "BlockModelsMixin", "FallingBlockEntityRendererMixin", + "LayerRenderStateMixin", "LifecycledResourceManagerImplMixin", "PistonBlockEntityRendererMixin", "RenderLayersMixin", diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 68812f0c..84ff0ef1 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -31,12 +31,12 @@ ], "depends": { - "minecraft": "1.21.3", + "minecraft": ">=1.21.4", "fabricloader": ">=0.15.0", - "fabric-api": ">=0.100.1" + "fabric-api": ">=0.113.0" }, "breaks": { - "sodium": "<0.6.2" + "sodium": "<0.6.6" }, "custom": { diff --git a/src/main/resources/resourcepacks/default/pack.mcmeta b/src/main/resources/resourcepacks/default/pack.mcmeta index 4953e5f1..3d53f135 100644 --- a/src/main/resources/resourcepacks/default/pack.mcmeta +++ b/src/main/resources/resourcepacks/default/pack.mcmeta @@ -1,7 +1,7 @@ { "pack": { - "pack_format": 42, - "supported_formats": [42, 999], + "pack_format": 46, + "supported_formats": [46, 999], "description": { "translate": "resourcePack.continuity.default.description" } diff --git a/src/main/resources/resourcepacks/glass_pane_culling_fix/pack.mcmeta b/src/main/resources/resourcepacks/glass_pane_culling_fix/pack.mcmeta index c09e24f3..98cc34eb 100644 --- a/src/main/resources/resourcepacks/glass_pane_culling_fix/pack.mcmeta +++ b/src/main/resources/resourcepacks/glass_pane_culling_fix/pack.mcmeta @@ -1,7 +1,7 @@ { "pack": { - "pack_format": 42, - "supported_formats": [42, 999], + "pack_format": 46, + "supported_formats": [46, 999], "description": { "translate": "resourcePack.continuity.glass_pane_culling_fix.description" }