From 1a2d2dc696e32839f434a25a0d088ee96742e65a Mon Sep 17 00:00:00 2001 From: LudoCrypt <60561627+LudoCrypt@users.noreply.github.com> Date: Sun, 24 Jul 2022 13:42:01 -0500 Subject: [PATCH] Submodels use Identifiers now --- gradle.properties | 2 +- .../limlib/access/BakedModelAccess.java | 12 ++++ .../ludocrypt/limlib/access/ModelAccess.java | 15 ---- .../limlib/access/UnbakedModelAccess.java | 12 ++++ .../client/render/WorldRendererMixin.java | 8 +-- ...hunkBuilderBuiltChunkRebuildTaskMixin.java | 4 +- .../sodium/ChunkRenderRebuildTaskMixin.java | 6 +- .../client/render/gui/ItemRendererMixin.java | 24 +++---- .../client/render/model/BakedModelMixin.java | 17 ++--- .../render/model/GeneralBakedModelMixin.java | 20 +++--- .../JsonUnbakedModelDeserializerMixin.java | 25 ++++--- .../render/model/JsonUnbakedModelMixin.java | 70 +++++++++++++------ 12 files changed, 123 insertions(+), 92 deletions(-) create mode 100644 src/main/java/net/ludocrypt/limlib/access/BakedModelAccess.java delete mode 100644 src/main/java/net/ludocrypt/limlib/access/ModelAccess.java create mode 100644 src/main/java/net/ludocrypt/limlib/access/UnbakedModelAccess.java diff --git a/gradle.properties b/gradle.properties index 28b3895..2d9f1e7 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,6 +8,6 @@ satin_version=1.8.0 sodium_version=mc1.19-0.4.2 iris_version=1.19.x-v1.2.5 -mod_version = 6.1.1 +mod_version = 6.2.0 maven_group = net.ludocrypt archives_base_name = limlib \ No newline at end of file diff --git a/src/main/java/net/ludocrypt/limlib/access/BakedModelAccess.java b/src/main/java/net/ludocrypt/limlib/access/BakedModelAccess.java new file mode 100644 index 0000000..05c4dcc --- /dev/null +++ b/src/main/java/net/ludocrypt/limlib/access/BakedModelAccess.java @@ -0,0 +1,12 @@ +package net.ludocrypt.limlib.access; + +import java.util.Map; + +import net.minecraft.client.render.model.BakedModel; +import net.minecraft.util.Identifier; + +public interface BakedModelAccess { + + public Map getSubModels(); + +} diff --git a/src/main/java/net/ludocrypt/limlib/access/ModelAccess.java b/src/main/java/net/ludocrypt/limlib/access/ModelAccess.java deleted file mode 100644 index 94cb841..0000000 --- a/src/main/java/net/ludocrypt/limlib/access/ModelAccess.java +++ /dev/null @@ -1,15 +0,0 @@ -package net.ludocrypt.limlib.access; - -import java.util.Optional; - -import org.jetbrains.annotations.Nullable; - -import net.minecraft.util.Identifier; - -public interface ModelAccess { - - public Optional getLiminalQuadRenderer(); - - public void setLiminalQuadRenderer(@Nullable Identifier id); - -} diff --git a/src/main/java/net/ludocrypt/limlib/access/UnbakedModelAccess.java b/src/main/java/net/ludocrypt/limlib/access/UnbakedModelAccess.java new file mode 100644 index 0000000..9b13c6d --- /dev/null +++ b/src/main/java/net/ludocrypt/limlib/access/UnbakedModelAccess.java @@ -0,0 +1,12 @@ +package net.ludocrypt.limlib.access; + +import java.util.Map; + +import net.minecraft.client.util.ModelIdentifier; +import net.minecraft.util.Identifier; + +public interface UnbakedModelAccess { + + public Map getSubModels(); + +} diff --git a/src/main/java/net/ludocrypt/limlib/mixin/client/render/WorldRendererMixin.java b/src/main/java/net/ludocrypt/limlib/mixin/client/render/WorldRendererMixin.java index eef7626..d284c92 100644 --- a/src/main/java/net/ludocrypt/limlib/mixin/client/render/WorldRendererMixin.java +++ b/src/main/java/net/ludocrypt/limlib/mixin/client/render/WorldRendererMixin.java @@ -16,8 +16,8 @@ import it.unimi.dsi.fastutil.objects.ObjectArrayList; import net.fabricmc.loader.api.FabricLoader; +import net.ludocrypt.limlib.access.BakedModelAccess; import net.ludocrypt.limlib.access.DimensionTypeAccess; -import net.ludocrypt.limlib.access.ModelAccess; import net.ludocrypt.limlib.access.RenderDataAccess; import net.ludocrypt.limlib.access.WorldRendererAccess; import net.ludocrypt.limlib.api.LiminalEffects; @@ -35,7 +35,6 @@ import net.minecraft.client.render.VertexConsumerProvider; import net.minecraft.client.render.WorldRenderer; import net.minecraft.client.render.WorldRenderer.ChunkInfo; -import net.minecraft.client.render.model.BakedModel; import net.minecraft.client.util.math.MatrixStack; import net.minecraft.client.world.ClientWorld; import net.minecraft.entity.Entity; @@ -178,10 +177,7 @@ public void renderBlocks(Framebuffer framebuffer, float tickDelta, MatrixStack m matrices.push(); matrices.translate(pos.getX() - camera.getPos().getX(), pos.getY() - camera.getPos().getY(), pos.getZ() - camera.getPos().getZ()); - BakedModel model = MinecraftClient.getInstance().getBlockRenderManager().getModel(state); - if (((ModelAccess) model).getLiminalQuadRenderer().isPresent()) { - LimlibRendering.LIMINAL_QUAD_RENDERER.get(((ModelAccess) model).getLiminalQuadRenderer().get()).renderModel(model, world, pos, state, matrices, camera); - } + ((BakedModelAccess) MinecraftClient.getInstance().getBlockRenderManager().getModel(state)).getSubModels().forEach((id, quads) -> LimlibRendering.LIMINAL_QUAD_RENDERER.get(id).renderModel(quads, world, pos, state, matrices, camera)); matrices.pop(); }); diff --git a/src/main/java/net/ludocrypt/limlib/mixin/client/render/chunk/ChunkBuilderBuiltChunkRebuildTaskMixin.java b/src/main/java/net/ludocrypt/limlib/mixin/client/render/chunk/ChunkBuilderBuiltChunkRebuildTaskMixin.java index 9cec8a4..39a204a 100644 --- a/src/main/java/net/ludocrypt/limlib/mixin/client/render/chunk/ChunkBuilderBuiltChunkRebuildTaskMixin.java +++ b/src/main/java/net/ludocrypt/limlib/mixin/client/render/chunk/ChunkBuilderBuiltChunkRebuildTaskMixin.java @@ -13,7 +13,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import org.spongepowered.asm.mixin.injection.callback.LocalCapture; -import net.ludocrypt.limlib.access.ModelAccess; +import net.ludocrypt.limlib.access.BakedModelAccess; import net.ludocrypt.limlib.access.RenderDataAccess; import net.minecraft.block.BlockState; import net.minecraft.client.render.RenderLayer; @@ -40,7 +40,7 @@ public class ChunkBuilderBuiltChunkRebuildTaskMixin { @Inject(method = "Lnet/minecraft/client/render/chunk/ChunkBuilder$BuiltChunk$RebuildTask;render(FFFLnet/minecraft/client/render/chunk/BlockBufferBuilderStorage;)Lnet/minecraft/client/render/chunk/ChunkBuilder$BuiltChunk$RebuildTask$RenderData;", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/render/chunk/ChunkRendererRegion;getBlockState(Lnet/minecraft/util/math/BlockPos;)Lnet/minecraft/block/BlockState;", ordinal = 0, shift = Shift.BEFORE), locals = LocalCapture.CAPTURE_FAILHARD) private void limlib$render(float cameraX, float cameraY, float cameraZ, BlockBufferBuilderStorage blockBufferBuilderStorage, CallbackInfoReturnable ci, RenderData renderData, int i, BlockPos blockPos, BlockPos blockPos2, ChunkOcclusionDataBuilder chunkOcclusionDataBuilder, ChunkRendererRegion chunkRendererRegion, MatrixStack matrixStack, Set set, Random random, BlockRenderManager blockRenderManager, Iterator var15, BlockPos blockPos3) { BlockState blockState = chunkRendererRegion.getBlockState(blockPos3); - if (((ModelAccess) blockRenderManager.getModel(blockState)).getLiminalQuadRenderer().isPresent()) { + if (!((BakedModelAccess) blockRenderManager.getModel(blockState)).getSubModels().isEmpty()) { ((RenderDataAccess) (Object) renderData).getCustomQuadData().put(blockPos3.toImmutable(), blockState); } } diff --git a/src/main/java/net/ludocrypt/limlib/mixin/client/render/chunk/sodium/ChunkRenderRebuildTaskMixin.java b/src/main/java/net/ludocrypt/limlib/mixin/client/render/chunk/sodium/ChunkRenderRebuildTaskMixin.java index 2f79925..ee053a0 100644 --- a/src/main/java/net/ludocrypt/limlib/mixin/client/render/chunk/sodium/ChunkRenderRebuildTaskMixin.java +++ b/src/main/java/net/ludocrypt/limlib/mixin/client/render/chunk/sodium/ChunkRenderRebuildTaskMixin.java @@ -18,7 +18,7 @@ import me.jellysquid.mods.sodium.client.render.pipeline.context.ChunkRenderCacheLocal; import me.jellysquid.mods.sodium.client.util.task.CancellationSource; import me.jellysquid.mods.sodium.client.world.WorldSlice; -import net.ludocrypt.limlib.access.ModelAccess; +import net.ludocrypt.limlib.access.BakedModelAccess; import net.ludocrypt.limlib.access.RenderDataAccess; import net.minecraft.block.BlockState; import net.minecraft.client.render.chunk.ChunkOcclusionDataBuilder; @@ -32,7 +32,7 @@ public class ChunkRenderRebuildTaskMixin { @Inject(method = "Lme/jellysquid/mods/sodium/client/render/chunk/tasks/ChunkRenderRebuildTask;performBuild(Lme/jellysquid/mods/sodium/client/gl/compile/ChunkBuildContext;Lme/jellysquid/mods/sodium/client/util/task/CancellationSource;)Lme/jellysquid/mods/sodium/client/render/chunk/compile/ChunkBuildResult;", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/math/BlockPos$Mutable;set(III)Lnet/minecraft/util/math/BlockPos$Mutable;", ordinal = 1, shift = Shift.AFTER, remap = false), locals = LocalCapture.CAPTURE_FAILHARD, remap = false, require = 0) private void limlib$performBuild$mapped(ChunkBuildContext buildContext, CancellationSource cancellationSource, CallbackInfoReturnable ci, ChunkRenderData.Builder renderData, ChunkOcclusionDataBuilder occluder, ChunkRenderBounds.Builder bounds, ChunkBuildBuffers buffers, ChunkRenderCacheLocal cache, WorldSlice slice, int minX, int minY, int minZ, int maxX, int maxY, int maxZ, Mutable blockPos, Mutable offset) { BlockState blockState = slice.getBlockState(blockPos); - if (((ModelAccess) cache.getBlockModels().getModel(blockState)).getLiminalQuadRenderer().isPresent()) { + if (!((BakedModelAccess) cache.getBlockModels().getModel(blockState)).getSubModels().isEmpty()) { ((RenderDataAccess) (Object) renderData).getCustomQuadData().put(blockPos.toImmutable(), blockState); } } @@ -41,7 +41,7 @@ public class ChunkRenderRebuildTaskMixin { @Inject(method = "Lme/jellysquid/mods/sodium/client/render/chunk/tasks/ChunkRenderRebuildTask;performBuild(Lme/jellysquid/mods/sodium/client/gl/compile/ChunkBuildContext;Lme/jellysquid/mods/sodium/client/util/task/CancellationSource;)Lme/jellysquid/mods/sodium/client/render/chunk/compile/ChunkBuildResult;", at = @At(value = "INVOKE", target = "Lnet/minecraft/class_2338$class_2339;method_10103(III)Lnet/minecraft/class_2338$class_2339;", ordinal = 1, shift = Shift.AFTER, remap = false), locals = LocalCapture.CAPTURE_FAILHARD, remap = false, require = 0) private void limlib$performBuild$unmapped(ChunkBuildContext buildContext, CancellationSource cancellationSource, CallbackInfoReturnable ci, ChunkRenderData.Builder renderData, ChunkOcclusionDataBuilder occluder, ChunkRenderBounds.Builder bounds, ChunkBuildBuffers buffers, ChunkRenderCacheLocal cache, WorldSlice slice, int minX, int minY, int minZ, int maxX, int maxY, int maxZ, Mutable blockPos, Mutable offset) { BlockState blockState = slice.getBlockState(blockPos); - if (((ModelAccess) cache.getBlockModels().getModel(blockState)).getLiminalQuadRenderer().isPresent()) { + if (!((BakedModelAccess) cache.getBlockModels().getModel(blockState)).getSubModels().isEmpty()) { ((RenderDataAccess) (Object) renderData).getCustomQuadData().put(blockPos.toImmutable(), blockState); } } diff --git a/src/main/java/net/ludocrypt/limlib/mixin/client/render/gui/ItemRendererMixin.java b/src/main/java/net/ludocrypt/limlib/mixin/client/render/gui/ItemRendererMixin.java index 15cefc8..4b79987 100644 --- a/src/main/java/net/ludocrypt/limlib/mixin/client/render/gui/ItemRendererMixin.java +++ b/src/main/java/net/ludocrypt/limlib/mixin/client/render/gui/ItemRendererMixin.java @@ -11,9 +11,9 @@ import com.google.common.collect.Lists; import net.fabricmc.loader.api.FabricLoader; +import net.ludocrypt.limlib.access.BakedModelAccess; import net.ludocrypt.limlib.access.IrisClientAccess; import net.ludocrypt.limlib.access.ItemRendererAccess; -import net.ludocrypt.limlib.access.ModelAccess; import net.ludocrypt.limlib.access.WorldRendererAccess; import net.ludocrypt.limlib.impl.LimlibRendering; import net.minecraft.client.MinecraftClient; @@ -31,20 +31,18 @@ public class ItemRendererMixin implements ItemRendererAccess { @Inject(method = "Lnet/minecraft/client/render/item/ItemRenderer;renderBakedItemModel(Lnet/minecraft/client/render/model/BakedModel;Lnet/minecraft/item/ItemStack;IILnet/minecraft/client/util/math/MatrixStack;Lnet/minecraft/client/render/VertexConsumer;)V", at = @At("HEAD")) private void limlib$renderBakedItemModel(BakedModel model, ItemStack stack, int light, int overlay, MatrixStack matrices, VertexConsumer vertices, CallbackInfo ci) { - if (((ModelAccess) model).getLiminalQuadRenderer().isPresent()) { - MinecraftClient client = MinecraftClient.getInstance(); + MinecraftClient client = MinecraftClient.getInstance(); - boolean isHandRendering = ((WorldRendererAccess) client.worldRenderer).isRenderingHands() || (FabricLoader.getInstance().isModLoaded("iris") && ((IrisClientAccess) client).isHandRenderingActive()); - boolean isItemRendering = ((WorldRendererAccess) client.worldRenderer).isRenderingItems(); + boolean isHandRendering = ((WorldRendererAccess) client.worldRenderer).isRenderingHands() || (FabricLoader.getInstance().isModLoaded("iris") && ((IrisClientAccess) client).isHandRenderingActive()); + boolean isItemRendering = ((WorldRendererAccess) client.worldRenderer).isRenderingItems(); - if (isHandRendering || isItemRendering || inGui) { - MatrixStack matrixStack = new MatrixStack(); - matrixStack.multiplyPositionMatrix(matrices.peek().getPositionMatrix().copy()); - List immediateRenderer = Lists.newArrayList(); - LimlibRendering.LIMINAL_QUAD_RENDERER.get(((ModelAccess) model).getLiminalQuadRenderer().get()).renderItemModel(model, client.world, stack.copy(), matrixStack, client.gameRenderer.getCamera(), inGui); - immediateRenderer.forEach(Runnable::run); - immediateRenderer.clear(); - } + if (isHandRendering || isItemRendering || inGui) { + MatrixStack matrixStack = new MatrixStack(); + matrixStack.multiplyPositionMatrix(matrices.peek().getPositionMatrix().copy()); + List immediateRenderer = Lists.newArrayList(); + ((BakedModelAccess) model).getSubModels().forEach((id, subModel) -> (isHandRendering ? LimlibRendering.LIMINAL_QUAD_RENDERER.get(id).heldItemRenderQueue : isItemRendering ? LimlibRendering.LIMINAL_QUAD_RENDERER.get(id).itemRenderQueue : immediateRenderer).add(() -> LimlibRendering.LIMINAL_QUAD_RENDERER.get(id).renderItemModel(subModel, client.world, stack.copy(), matrixStack, client.gameRenderer.getCamera(), inGui))); + immediateRenderer.forEach(Runnable::run); + immediateRenderer.clear(); } } diff --git a/src/main/java/net/ludocrypt/limlib/mixin/client/render/model/BakedModelMixin.java b/src/main/java/net/ludocrypt/limlib/mixin/client/render/model/BakedModelMixin.java index a213b97..993ec9e 100644 --- a/src/main/java/net/ludocrypt/limlib/mixin/client/render/model/BakedModelMixin.java +++ b/src/main/java/net/ludocrypt/limlib/mixin/client/render/model/BakedModelMixin.java @@ -1,24 +1,21 @@ package net.ludocrypt.limlib.mixin.client.render.model; -import java.util.Optional; +import java.util.Map; -import org.jetbrains.annotations.Nullable; import org.spongepowered.asm.mixin.Mixin; -import net.ludocrypt.limlib.access.ModelAccess; +import com.google.common.collect.Maps; + +import net.ludocrypt.limlib.access.BakedModelAccess; import net.minecraft.client.render.model.BakedModel; import net.minecraft.util.Identifier; @Mixin(BakedModel.class) -public interface BakedModelMixin extends ModelAccess { - - @Override - default Optional getLiminalQuadRenderer() { - return Optional.empty(); - } +public interface BakedModelMixin extends BakedModelAccess { @Override - default void setLiminalQuadRenderer(@Nullable Identifier id) { + default Map getSubModels() { + return Maps.newHashMap(); } } diff --git a/src/main/java/net/ludocrypt/limlib/mixin/client/render/model/GeneralBakedModelMixin.java b/src/main/java/net/ludocrypt/limlib/mixin/client/render/model/GeneralBakedModelMixin.java index 5b74f26..14f958e 100644 --- a/src/main/java/net/ludocrypt/limlib/mixin/client/render/model/GeneralBakedModelMixin.java +++ b/src/main/java/net/ludocrypt/limlib/mixin/client/render/model/GeneralBakedModelMixin.java @@ -1,27 +1,25 @@ package net.ludocrypt.limlib.mixin.client.render.model; -import java.util.Optional; +import java.util.Map; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Unique; -import net.ludocrypt.limlib.access.ModelAccess; +import com.google.common.collect.Maps; + +import net.ludocrypt.limlib.access.BakedModelAccess; +import net.minecraft.client.render.model.BakedModel; import net.minecraft.util.Identifier; @Mixin(targets = { "net/minecraft/client/render/model/BasicBakedModel", "net/minecraft/client/render/model/BuiltinBakedModel", "net/minecraft/client/render/model/MultipartBakedModel", "net/minecraft/client/render/model/WeightedBakedModel", "net/fabricmc/fabric/api/renderer/v1/model/ForwardingBakedModel" }) -public class GeneralBakedModelMixin implements ModelAccess { +public class GeneralBakedModelMixin implements BakedModelAccess { @Unique - private Optional liminalQuadRenderer = Optional.empty(); - - @Override - public Optional getLiminalQuadRenderer() { - return liminalQuadRenderer; - } + private Map subQuads = Maps.newHashMap(); @Override - public void setLiminalQuadRenderer(Identifier id) { - liminalQuadRenderer = Optional.ofNullable(id); + public Map getSubModels() { + return subQuads; } } diff --git a/src/main/java/net/ludocrypt/limlib/mixin/client/render/model/JsonUnbakedModelDeserializerMixin.java b/src/main/java/net/ludocrypt/limlib/mixin/client/render/model/JsonUnbakedModelDeserializerMixin.java index 9370c37..6234aef 100644 --- a/src/main/java/net/ludocrypt/limlib/mixin/client/render/model/JsonUnbakedModelDeserializerMixin.java +++ b/src/main/java/net/ludocrypt/limlib/mixin/client/render/model/JsonUnbakedModelDeserializerMixin.java @@ -1,22 +1,22 @@ package net.ludocrypt.limlib.mixin.client.render.model; import java.lang.reflect.Type; -import java.util.List; +import java.util.Map; 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 com.google.common.collect.Maps; import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonElement; import com.google.gson.JsonObject; -import net.ludocrypt.limlib.access.ModelAccess; +import net.ludocrypt.limlib.access.UnbakedModelAccess; import net.ludocrypt.limlib.impl.LimlibRendering; import net.minecraft.client.render.model.json.JsonUnbakedModel; -import net.minecraft.client.render.model.json.ModelElement; +import net.minecraft.client.util.ModelIdentifier; import net.minecraft.util.Identifier; @Mixin(JsonUnbakedModel.Deserializer.class) @@ -24,15 +24,18 @@ public abstract class JsonUnbakedModelDeserializerMixin { @Inject(method = "Lnet/minecraft/client/render/model/json/JsonUnbakedModel$Deserializer;deserialize(Lcom/google/gson/JsonElement;Ljava/lang/reflect/Type;Lcom/google/gson/JsonDeserializationContext;)Lnet/minecraft/client/render/model/json/JsonUnbakedModel;", at = @At("RETURN"), cancellable = true) private void limlib$deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext, CallbackInfoReturnable ci) { + Map map = Maps.newHashMap(); JsonObject jsonObject = jsonElement.getAsJsonObject(); - if (jsonObject.has("limlib_renderer")) { - if (LimlibRendering.LIMINAL_QUAD_RENDERER.containsId(new Identifier(jsonObject.get("limlib_renderer").getAsString()))) { - ((ModelAccess) ci.getReturnValue()).setLiminalQuadRenderer(new Identifier(jsonObject.get("limlib_renderer").getAsString())); - } + if (jsonObject.has("limlib_extra")) { + LimlibRendering.LIMINAL_QUAD_RENDERER.getEntrySet().forEach((entry) -> { + JsonObject limlibExtra = jsonObject.get("limlib_extra").getAsJsonObject(); + if (limlibExtra.has(entry.getKey().getValue().toString())) { + JsonObject renderer = limlibExtra.get(entry.getKey().getValue().toString()).getAsJsonObject(); + map.put(entry.getKey().getValue(), new ModelIdentifier(renderer.getAsString())); + } + }); } + ((UnbakedModelAccess) ci.getReturnValue()).getSubModels().putAll(map); } - @Shadow - protected abstract List elementsFromJson(JsonDeserializationContext context, JsonObject json); - } diff --git a/src/main/java/net/ludocrypt/limlib/mixin/client/render/model/JsonUnbakedModelMixin.java b/src/main/java/net/ludocrypt/limlib/mixin/client/render/model/JsonUnbakedModelMixin.java index a86f205..097a861 100644 --- a/src/main/java/net/ludocrypt/limlib/mixin/client/render/model/JsonUnbakedModelMixin.java +++ b/src/main/java/net/ludocrypt/limlib/mixin/client/render/model/JsonUnbakedModelMixin.java @@ -1,53 +1,83 @@ package net.ludocrypt.limlib.mixin.client.render.model; -import java.util.Optional; +import java.util.Collection; +import java.util.HashSet; +import java.util.Map; +import java.util.Objects; +import java.util.Set; import java.util.function.Function; +import org.slf4j.Logger; +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.At.Shift; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; +import org.spongepowered.asm.mixin.injection.callback.LocalCapture; -import net.ludocrypt.limlib.access.ModelAccess; +import com.google.common.collect.Maps; +import com.google.common.collect.Sets; +import com.mojang.datafixers.util.Pair; + +import net.ludocrypt.limlib.access.BakedModelAccess; +import net.ludocrypt.limlib.access.UnbakedModelAccess; import net.minecraft.client.render.model.BakedModel; -import net.minecraft.client.render.model.BakedQuad; import net.minecraft.client.render.model.ModelBakeSettings; import net.minecraft.client.render.model.ModelLoader; +import net.minecraft.client.render.model.UnbakedModel; import net.minecraft.client.render.model.json.JsonUnbakedModel; -import net.minecraft.client.render.model.json.ModelElement; -import net.minecraft.client.render.model.json.ModelElementFace; import net.minecraft.client.texture.Sprite; +import net.minecraft.client.util.ModelIdentifier; import net.minecraft.client.util.SpriteIdentifier; import net.minecraft.util.Identifier; -import net.minecraft.util.math.Direction; @Mixin(JsonUnbakedModel.class) -public abstract class JsonUnbakedModelMixin implements ModelAccess { +public abstract class JsonUnbakedModelMixin implements UnbakedModelAccess { - @Unique - private Optional liminalQuadRenderer = Optional.empty(); + @Shadow + @Final + private static Logger LOGGER; - @Inject(method = "Lnet/minecraft/client/render/model/json/JsonUnbakedModel;bake(Lnet/minecraft/client/render/model/ModelLoader;Lnet/minecraft/client/render/model/json/JsonUnbakedModel;Ljava/util/function/Function;Lnet/minecraft/client/render/model/ModelBakeSettings;Lnet/minecraft/util/Identifier;Z)Lnet/minecraft/client/render/model/BakedModel;", at = @At("RETURN"), cancellable = true) - private void limlib$bake(ModelLoader loader, JsonUnbakedModel parent, Function textureGetter, ModelBakeSettings settings, Identifier id, boolean hasDepth, CallbackInfoReturnable ci) { - ((ModelAccess) ci.getReturnValue()).setLiminalQuadRenderer(liminalQuadRenderer.orElse(null)); - } + @Unique + private Map subModels = Maps.newHashMap(); @Shadow - private native static BakedQuad createQuad(ModelElement element, ModelElementFace elementFace, Sprite sprite, Direction side, ModelBakeSettings settings, Identifier id); + public String id; @Shadow - public abstract SpriteIdentifier resolveSprite(String spriteName); + protected JsonUnbakedModel parent; - @Override - public Optional getLiminalQuadRenderer() { - return liminalQuadRenderer; + @Inject(method = "Lnet/minecraft/client/render/model/json/JsonUnbakedModel;getModelDependencies()Ljava/util/Collection;", at = @At("RETURN"), cancellable = true) + private void limlib$getModelDependencies(CallbackInfoReturnable> ci) { + HashSet set = Sets.newHashSet(); + set.addAll(ci.getReturnValue()); + set.addAll(subModels.values()); + ci.setReturnValue(set); + } + + @Inject(method = "Lnet/minecraft/client/render/model/json/JsonUnbakedModel;getTextureDependencies(Ljava/util/function/Function;Ljava/util/Set;)Ljava/util/Collection;", at = @At(value = "INVOKE", target = "Ljava/util/List;forEach(Ljava/util/function/Consumer;)V", ordinal = 0, shift = Shift.BEFORE), locals = LocalCapture.CAPTURE_FAILHARD) + private void limlib$getTextureDependencies(Function unbakedModelGetter, Set> unresolvedTextureReferences, CallbackInfoReturnable> ci, Set set, JsonUnbakedModel jsonUnbakedModel, Set set2) { + this.getSubModels().values().forEach(subModel -> { + UnbakedModel unbakedModel = (UnbakedModel) unbakedModelGetter.apply(subModel); + if (!Objects.equals(unbakedModel, (JsonUnbakedModel) (Object) this)) { + set2.addAll(unbakedModel.getTextureDependencies(unbakedModelGetter, unresolvedTextureReferences)); + } + }); + } + + @Inject(method = "Lnet/minecraft/client/render/model/json/JsonUnbakedModel;bake(Lnet/minecraft/client/render/model/ModelLoader;Lnet/minecraft/client/render/model/json/JsonUnbakedModel;Ljava/util/function/Function;Lnet/minecraft/client/render/model/ModelBakeSettings;Lnet/minecraft/util/Identifier;Z)Lnet/minecraft/client/render/model/BakedModel;", at = @At("RETURN"), cancellable = true) + private void limlib$bake(ModelLoader loader, JsonUnbakedModel parent, Function textureGetter, ModelBakeSettings settings, Identifier id, boolean hasDepth, CallbackInfoReturnable ci) { + Map subModels = Maps.newHashMap(); + this.getSubModels().forEach((rendererId, modelId) -> subModels.put(rendererId, loader.getOrLoadModel(modelId).bake(loader, textureGetter, settings, modelId))); + ((BakedModelAccess) ci.getReturnValue()).getSubModels().putAll(subModels); } @Override - public void setLiminalQuadRenderer(Identifier id) { - liminalQuadRenderer = Optional.ofNullable(id); + public Map getSubModels() { + return subModels; } }