Make CTM work on 1.21
This commit is contained in:
parent
631ad0528b
commit
7db5d6a1da
|
|
@ -1,5 +1,11 @@
|
||||||
package org.embeddedt.modernfix.api.entrypoint;
|
package org.embeddedt.modernfix.api.entrypoint;
|
||||||
|
|
||||||
|
import net.minecraft.client.resources.model.BakedModel;
|
||||||
|
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;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implement this interface in a mod class and add it to "modernfix:integration_v1" in your mod metadata file
|
* Implement this interface in a mod class and add it to "modernfix:integration_v1" in your mod metadata file
|
||||||
* to integrate with ModernFix's features.
|
* to integrate with ModernFix's features.
|
||||||
|
|
@ -13,4 +19,19 @@ public interface ModernFixClientIntegration {
|
||||||
*/
|
*/
|
||||||
default void onDynamicResourcesStatusChange(boolean enabled) {
|
default void onDynamicResourcesStatusChange(boolean enabled) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called to allow mods to observe the loading of a baked model and either make changes to it or wrap it with their
|
||||||
|
* own instance.
|
||||||
|
*
|
||||||
|
* @param location the ResourceLocation of the model (this may be a ModelResourceLocation)
|
||||||
|
* @param originalModel the original model
|
||||||
|
* @param bakery the model bakery - do not touch internal fields as they probably don't behave the way you expect
|
||||||
|
* with dynamic resources on
|
||||||
|
* @param textureGetter function to retrieve textures for this model
|
||||||
|
* @return the model which should actually be loaded for this resource location
|
||||||
|
*/
|
||||||
|
default BakedModel onBakedModelLoad(ModelResourceLocation location, UnbakedModel baseModel, BakedModel originalModel, ModelState state, ModelBakery bakery, ModelBakery.TextureGetter textureGetter) {
|
||||||
|
return originalModel;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
|
||||||
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
||||||
import net.minecraft.client.color.block.BlockColors;
|
import net.minecraft.client.color.block.BlockColors;
|
||||||
import net.minecraft.client.resources.model.BakedModel;
|
import net.minecraft.client.resources.model.BakedModel;
|
||||||
|
import net.minecraft.client.resources.model.BlockModelRotation;
|
||||||
import net.minecraft.client.resources.model.BlockStateModelLoader;
|
import net.minecraft.client.resources.model.BlockStateModelLoader;
|
||||||
import net.minecraft.client.resources.model.ModelBakery;
|
import net.minecraft.client.resources.model.ModelBakery;
|
||||||
import net.minecraft.client.resources.model.ModelResourceLocation;
|
import net.minecraft.client.resources.model.ModelResourceLocation;
|
||||||
|
|
@ -14,7 +15,9 @@ import net.minecraft.core.DefaultedRegistry;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.util.profiling.ProfilerFiller;
|
import net.minecraft.util.profiling.ProfilerFiller;
|
||||||
import org.embeddedt.modernfix.ModernFix;
|
import org.embeddedt.modernfix.ModernFix;
|
||||||
|
import org.embeddedt.modernfix.ModernFixClient;
|
||||||
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
|
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
|
||||||
|
import org.embeddedt.modernfix.api.entrypoint.ModernFixClientIntegration;
|
||||||
import org.embeddedt.modernfix.duck.IBlockStateModelLoader;
|
import org.embeddedt.modernfix.duck.IBlockStateModelLoader;
|
||||||
import org.embeddedt.modernfix.duck.IExtendedModelBakery;
|
import org.embeddedt.modernfix.duck.IExtendedModelBakery;
|
||||||
import org.embeddedt.modernfix.util.DynamicOverridableMap;
|
import org.embeddedt.modernfix.util.DynamicOverridableMap;
|
||||||
|
|
@ -129,6 +132,9 @@ public abstract class ModelBakeryMixin implements IExtendedModelBakery {
|
||||||
ModernFix.LOGGER.error("Failed to load model " + location);
|
ModernFix.LOGGER.error("Failed to load model " + location);
|
||||||
model = bakedMissingModel;
|
model = bakedMissingModel;
|
||||||
}
|
}
|
||||||
|
for(ModernFixClientIntegration integration : ModernFixClient.CLIENT_INTEGRATIONS) {
|
||||||
|
model = integration.onBakedModelLoad(location, prototype, model, BlockModelRotation.X0_Y0, (ModelBakery)(Object)this, this.textureGetter);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,9 @@ accessible field net/minecraft/client/renderer/block/model/BlockModel GSON Lcom/
|
||||||
accessible class net/minecraft/server/level/ChunkMap$DistanceManager
|
accessible class net/minecraft/server/level/ChunkMap$DistanceManager
|
||||||
accessible class net/minecraft/client/resources/model/ModelBakery$BakedCacheKey
|
accessible class net/minecraft/client/resources/model/ModelBakery$BakedCacheKey
|
||||||
accessible method net/minecraft/client/resources/model/ModelBakery$BakedCacheKey <init> (Lnet/minecraft/resources/ResourceLocation;Lcom/mojang/math/Transformation;Z)V
|
accessible method net/minecraft/client/resources/model/ModelBakery$BakedCacheKey <init> (Lnet/minecraft/resources/ResourceLocation;Lcom/mojang/math/Transformation;Z)V
|
||||||
|
accessible class net/minecraft/client/resources/model/ModelBakery$ModelBakerImpl
|
||||||
|
accessible method net/minecraft/client/resources/model/ModelBakery$ModelBakerImpl <init> (Lnet/minecraft/client/resources/model/ModelBakery;Lnet/minecraft/client/resources/model/ModelBakery$TextureGetter;Lnet/minecraft/client/resources/model/ModelResourceLocation;)V
|
||||||
|
accessible method net/minecraft/client/resources/model/ModelBakery getModel (Lnet/minecraft/resources/ResourceLocation;)Lnet/minecraft/client/resources/model/UnbakedModel;
|
||||||
accessible class net/minecraft/world/level/chunk/PalettedContainer$Data
|
accessible class net/minecraft/world/level/chunk/PalettedContainer$Data
|
||||||
accessible field net/minecraft/server/MinecraftServer resources Lnet/minecraft/server/MinecraftServer$ReloadableResources;
|
accessible field net/minecraft/server/MinecraftServer resources Lnet/minecraft/server/MinecraftServer$ReloadableResources;
|
||||||
accessible class net/minecraft/server/MinecraftServer$ReloadableResources
|
accessible class net/minecraft/server/MinecraftServer$ReloadableResources
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ parchment_version=2024.07.07
|
||||||
refined_storage_version=4392788
|
refined_storage_version=4392788
|
||||||
jei_version=19.0.0.9
|
jei_version=19.0.0.9
|
||||||
rei_version=13.0.678
|
rei_version=13.0.678
|
||||||
ctm_version=1.20.1-1.1.8+4
|
ctm_version=1.21-1.2.0+2
|
||||||
kubejs_version=1902.6.0-build.142
|
kubejs_version=1902.6.0-build.142
|
||||||
rhino_version=1902.2.2-build.268
|
rhino_version=1902.2.2-build.268
|
||||||
supported_minecraft_versions=1.21
|
supported_minecraft_versions=1.21
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ dependencies {
|
||||||
modCompileOnly("me.shedaniel:RoughlyEnoughItems-forge:${rei_version}") { transitive false }
|
modCompileOnly("me.shedaniel:RoughlyEnoughItems-forge:${rei_version}") { transitive false }
|
||||||
modCompileOnly("dev.latvian.mods:kubejs-forge:${kubejs_version}")
|
modCompileOnly("dev.latvian.mods:kubejs-forge:${kubejs_version}")
|
||||||
//modRuntimeOnly("curse.maven:ferritecore-429235:4441949")
|
//modRuntimeOnly("curse.maven:ferritecore-429235:4441949")
|
||||||
modCompileOnly files("deps/ctm.jar")
|
modCompileOnly("team.chisel.ctm:CTM:${ctm_version}")
|
||||||
|
|
||||||
modCompileOnly("curse.maven:supermartijncore-454372:4455391")
|
modCompileOnly("curse.maven:supermartijncore-454372:4455391")
|
||||||
modCompileOnly("vazkii.patchouli:Patchouli:1.19.2-77")
|
modCompileOnly("vazkii.patchouli:Patchouli:1.19.2-77")
|
||||||
|
|
|
||||||
Binary file not shown.
|
|
@ -0,0 +1,16 @@
|
||||||
|
package org.embeddedt.modernfix.neoforge.mixin.perf.dynamic_resources.ctm;
|
||||||
|
|
||||||
|
import net.minecraft.client.resources.model.BakedModel;
|
||||||
|
import net.minecraft.client.resources.model.ModelBakery;
|
||||||
|
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Mixin(ModelBakery.class)
|
||||||
|
@ClientOnlyMixin
|
||||||
|
public interface CTMModelBakeryAccessor {
|
||||||
|
@Accessor("bakedCache")
|
||||||
|
Map<ModelBakery.BakedCacheKey, BakedModel> mfix$getBakedCache();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,114 @@
|
||||||
|
package org.embeddedt.modernfix.neoforge.mixin.perf.dynamic_resources.ctm;
|
||||||
|
|
||||||
|
import com.google.common.collect.Multimap;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
import com.mojang.datafixers.util.Pair;
|
||||||
|
import net.minecraft.client.resources.model.*;
|
||||||
|
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.Final;
|
||||||
|
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.CallbackInfo;
|
||||||
|
import team.chisel.ctm.CTM;
|
||||||
|
import team.chisel.ctm.api.model.IModelCTM;
|
||||||
|
import team.chisel.ctm.client.model.AbstractCTMBakedModel;
|
||||||
|
import team.chisel.ctm.client.model.ModelCTM;
|
||||||
|
import team.chisel.ctm.client.texture.IMetadataSectionCTM;
|
||||||
|
import team.chisel.ctm.client.util.ResourceUtil;
|
||||||
|
import team.chisel.ctm.client.util.TextureMetadataHandler;
|
||||||
|
|
||||||
|
import javax.annotation.Nonnull;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
@Mixin(TextureMetadataHandler.class)
|
||||||
|
@RequiresMod("ctm")
|
||||||
|
@ClientOnlyMixin
|
||||||
|
public abstract class TextureMetadataHandlerMixin implements ModernFixClientIntegration {
|
||||||
|
|
||||||
|
@Shadow(remap = false) @Nonnull protected abstract BakedModel wrap(UnbakedModel model, BakedModel object) throws IOException;
|
||||||
|
|
||||||
|
@Shadow(remap = false) @Final private Multimap<ResourceLocation, Material> scrapedTextures;
|
||||||
|
|
||||||
|
@Inject(method = "<init>", at = @At("RETURN"))
|
||||||
|
private void subscribeDynamic(CallbackInfo ci) {
|
||||||
|
ModernFixClient.CLIENT_INTEGRATIONS.add(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(method = { "onModelBake(Lnet/neoforged/neoforge/client/event/ModelEvent$BakingCompleted;)V", "onModelBake(Lnet/neoforged/neoforge/client/event/ModelEvent$ModifyBakingResult;)V" }, at = @At("HEAD"), cancellable = true, remap = false)
|
||||||
|
private void noIteration(CallbackInfo ci) {
|
||||||
|
ci.cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BakedModel onBakedModelLoad(ModelResourceLocation mrl, UnbakedModel rootModel, BakedModel baked, ModelState state, ModelBakery bakery, ModelBakery.TextureGetter getter) {
|
||||||
|
if (!(baked instanceof AbstractCTMBakedModel) && !baked.isCustomRenderer()) {
|
||||||
|
Deque<ResourceLocation> dependencies = new ArrayDeque<>();
|
||||||
|
Set<ResourceLocation> seenModels = new HashSet<>();
|
||||||
|
dependencies.push(mrl.id());
|
||||||
|
seenModels.add(mrl.id());
|
||||||
|
boolean shouldWrap = false;
|
||||||
|
Set<Pair<String, String>> errors = new HashSet<>();
|
||||||
|
// 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 == mrl.id() ? rootModel : bakery.getModel(dep);
|
||||||
|
} catch (Exception e) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Collection<Material> textures = Sets.newHashSet(scrapedTextures.get(dep));
|
||||||
|
Collection<ResourceLocation> newDependencies = model.getDependencies();
|
||||||
|
for (Material tex : textures) {
|
||||||
|
IMetadataSectionCTM meta = null;
|
||||||
|
// Cache all dependent texture metadata
|
||||||
|
try {
|
||||||
|
meta = ResourceUtil.getMetadata(ResourceUtil.spriteToAbsolute(tex.texture())).orElse(null); // TODO, lazy
|
||||||
|
} catch (IOException e) {} // Fallthrough
|
||||||
|
if (meta != null) {
|
||||||
|
// At least one texture has CTM metadata, so we should wrap this model
|
||||||
|
shouldWrap = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (ResourceLocation newDep : newDependencies) {
|
||||||
|
if (seenModels.add(newDep)) {
|
||||||
|
dependencies.push(newDep);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (shouldWrap) {
|
||||||
|
try {
|
||||||
|
baked = wrap(rootModel, baked);
|
||||||
|
handleInit(mrl, baked, bakery, getter);
|
||||||
|
dependencies.clear();
|
||||||
|
} catch (IOException e) {
|
||||||
|
CTM.logger.error("Could not wrap model " + mrl + ". Aborting...", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return baked;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void handleInit(ModelResourceLocation key, BakedModel wrappedModel, ModelBakery bakery, ModelBakery.TextureGetter spriteGetter) {
|
||||||
|
if(wrappedModel instanceof AbstractCTMBakedModel baked) {
|
||||||
|
IModelCTM var10 = baked.getModel();
|
||||||
|
if (var10 instanceof ModelCTM ctmModel) {
|
||||||
|
if (!ctmModel.isInitialized()) {
|
||||||
|
// Clear the baked cache as upstream CTM does
|
||||||
|
((CTMModelBakeryAccessor)bakery).mfix$getBakedCache().clear();
|
||||||
|
ModelBakery.ModelBakerImpl baker = bakery.new ModelBakerImpl(spriteGetter, key);
|
||||||
|
ctmModel.bake(baker, Material::sprite, BlockModelRotation.X0_Y0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user