From 64a427fa62a9d31c9d0851d4952778f2071e6c08 Mon Sep 17 00:00:00 2001 From: embeddedt <42941056+embeddedt@users.noreply.github.com> Date: Thu, 26 Dec 2024 14:51:20 -0500 Subject: [PATCH] Add LDLib connected textures integration --- forge/build.gradle | 1 + .../ldlib/ClientProxyImplMixin.java | 102 ++++++++++++++++++ gradle.properties | 1 + 3 files changed, 104 insertions(+) create mode 100644 forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/dynamic_resources/ldlib/ClientProxyImplMixin.java diff --git a/forge/build.gradle b/forge/build.gradle index 101dba1a..4d5881ec 100644 --- a/forge/build.gradle +++ b/forge/build.gradle @@ -56,6 +56,7 @@ dependencies { modCompileOnly("dev.latvian.mods:kubejs-forge:${kubejs_version}") //modRuntimeOnly("curse.maven:ferritecore-429235:4441949") modCompileOnly("curse.maven:ctm-267602:${ctm_version}") + modCompileOnly("curse.maven:ldlib-626676:${ldlib_version}") modCompileOnly("curse.maven:supermartijncore-454372:4455391") modCompileOnly("vazkii.patchouli:Patchouli:1.19.2-77") diff --git a/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/dynamic_resources/ldlib/ClientProxyImplMixin.java b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/dynamic_resources/ldlib/ClientProxyImplMixin.java new file mode 100644 index 00000000..de4e80db --- /dev/null +++ b/forge/src/main/java/org/embeddedt/modernfix/forge/mixin/perf/dynamic_resources/ldlib/ClientProxyImplMixin.java @@ -0,0 +1,102 @@ +package org.embeddedt.modernfix.forge.mixin.perf.dynamic_resources.ldlib; + +import com.lowdragmc.lowdraglib.LDLib; +import com.lowdragmc.lowdraglib.client.ClientProxy; +import com.lowdragmc.lowdraglib.client.forge.ClientProxyImpl; +import com.lowdragmc.lowdraglib.client.model.custommodel.LDLMetadataSection; +import com.lowdragmc.lowdraglib.client.model.forge.CustomBakedModelImpl; +import com.lowdragmc.lowdraglib.client.model.forge.LDLRendererModel; +import net.minecraft.client.renderer.texture.TextureAtlasSprite; +import net.minecraft.client.resources.model.BakedModel; +import net.minecraft.client.resources.model.Material; +import net.minecraft.client.resources.model.ModelBakery; +import net.minecraft.client.resources.model.ModelResourceLocation; +import net.minecraft.client.resources.model.ModelState; +import net.minecraft.client.resources.model.UnbakedModel; +import net.minecraft.resources.ResourceLocation; +import org.embeddedt.modernfix.ModernFixClient; +import org.embeddedt.modernfix.annotation.ClientOnlyMixin; +import org.embeddedt.modernfix.annotation.RequiresMod; +import org.embeddedt.modernfix.api.entrypoint.ModernFixClientIntegration; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.util.ArrayDeque; +import java.util.Deque; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.function.Function; + +@Mixin(ClientProxyImpl.class) +@ClientOnlyMixin +@RequiresMod("ldlib") +public abstract class ClientProxyImplMixin implements ModernFixClientIntegration { + @Inject(method = "", at = @At("RETURN")) + private void registerIntegration(CallbackInfo ci) { + ModernFixClient.CLIENT_INTEGRATIONS.add(this); + } + + @Redirect(method = "modelBake", at = @At(value = "INVOKE", target = "Ljava/util/Map;entrySet()Ljava/util/Set;", ordinal = 0), remap = false) + private Set disableLoop(Map map) { + return Set.of(); + } + + @Override + public BakedModel onBakedModelLoad(ResourceLocation rl, UnbakedModel rootModel, BakedModel baked, ModelState state, ModelBakery bakery, Function textureGetter) { + if (baked == null) { + return null; + } + if (rl instanceof ModelResourceLocation && rootModel != null) { + if (baked instanceof LDLRendererModel) { + return baked; + } + if (baked.isCustomRenderer()) { // Nothing we can add to builtin models + return baked; + } + Deque dependencies = new ArrayDeque<>(); + Set seenModels = new HashSet<>(); + dependencies.push(rl); + seenModels.add(rl); + boolean shouldWrap = ClientProxy.WRAPPED_MODELS.getOrDefault(rl, false); + // Breadth-first loop through dependencies, exiting as soon as a CTM texture is found, and skipping duplicates/cycles + while (!shouldWrap && !dependencies.isEmpty()) { + ResourceLocation dep = dependencies.pop(); + UnbakedModel model; + try { + model = dep == rl ? rootModel : bakery.getModel(dep); + } catch (Exception e) { + continue; + } + try { + Set textures = new HashSet<>(ClientProxy.SCRAPED_TEXTURES.get(dep)); + for (Material tex : textures) { + // Cache all dependent texture metadata + // At least one texture has CTM metadata, so we should wrap this baked + if (!LDLMetadataSection.getMetadata(LDLMetadataSection.spriteToAbsolute(tex.texture())).isMissing()) { // TODO lazy + shouldWrap = true; + break; + } + } + if (!shouldWrap) { + for (ResourceLocation newDep : model.getDependencies()) { + if (seenModels.add(newDep)) { + dependencies.push(newDep); + } + } + } + } catch (Exception e) { + LDLib.LOGGER.error("Error loading baked dependency {} for baked {}. Skipping...", dep, rl, e); + } + } + ClientProxy.WRAPPED_MODELS.put(rl, shouldWrap); + if (shouldWrap) { + return new CustomBakedModelImpl(baked); + } + } + return baked; + } +} diff --git a/gradle.properties b/gradle.properties index 3c239fa4..77d5cc8e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -13,6 +13,7 @@ refined_storage_version=4392788 jei_version=15.8.0.11 rei_version=11.0.597 ctm_version=5983309 +ldlib_version=5927130 kubejs_version=1902.6.0-build.142 rhino_version=1902.2.2-build.268 supported_minecraft_versions=1.20.1