Rewrite 1.19.4 Fabric model baker mixin for compatibility purposes
This commit is contained in:
parent
d4bfe17a72
commit
545c68f122
11
build.gradle
11
build.gradle
|
|
@ -41,6 +41,17 @@ allprojects {
|
|||
includeGroup "curse.maven"
|
||||
}
|
||||
}
|
||||
exclusiveContent {
|
||||
forRepository {
|
||||
maven {
|
||||
name = "Modrinth"
|
||||
url = "https://api.modrinth.com/maven"
|
||||
}
|
||||
}
|
||||
filter {
|
||||
includeGroup "maven.modrinth"
|
||||
}
|
||||
}
|
||||
maven {
|
||||
name = 'ParchmentMC'
|
||||
url = 'https://maven.parchmentmc.org'
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
package org.embeddedt.modernfix.fabric.mixin.perf.dynamic_resources;
|
||||
|
||||
import net.fabricmc.loader.api.FabricLoader;
|
||||
import net.minecraft.client.renderer.block.model.BlockModel;
|
||||
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
||||
import net.minecraft.client.resources.model.*;
|
||||
import net.minecraft.core.registries.BuiltInRegistries;
|
||||
|
|
@ -16,14 +15,16 @@ 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.ModifyVariable;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
|
||||
@Mixin(ModelBakery.ModelBakerImpl.class)
|
||||
@Mixin(value = ModelBakery.ModelBakerImpl.class, priority = 600)
|
||||
public abstract class ModelBakerImplMixin {
|
||||
private static final boolean debugDynamicModelLoading = Boolean.getBoolean("modernfix.debugDynamicModelLoading");
|
||||
@Shadow @Final private ModelBakery field_40571;
|
||||
|
|
@ -49,41 +50,85 @@ public abstract class ModelBakerImplMixin {
|
|||
}
|
||||
}
|
||||
|
||||
private void createBakedMissingModelIfNeeded(IExtendedModelBakery extendedBakery, UnbakedModel iunbakedmodel, ModelState arg2, ResourceLocation arg) {
|
||||
if(extendedBakery.getBakedMissingModel() == null) {
|
||||
extendedBakery.setBakedMissingModel(iunbakedmodel.bake((ModelBaker)this, this.modelTextureGetter, arg2, arg));
|
||||
((DynamicBakedModelProvider)this.field_40571.getBakedTopLevelModels()).setMissingModel(extendedBakery.getBakedMissingModel());
|
||||
}
|
||||
}
|
||||
|
||||
@Inject(method = "bake", at = @At("HEAD"), cancellable = true)
|
||||
public void getOrLoadBakedModelDynamic(ResourceLocation arg, ModelState arg2, CallbackInfoReturnable<BakedModel> cir) {
|
||||
private boolean wasMissingModel = false;
|
||||
|
||||
@Inject(method = "getModel", at = @At("HEAD"), cancellable = true)
|
||||
private void obtainModel(ResourceLocation arg, CallbackInfoReturnable<UnbakedModel> cir) {
|
||||
if(debugDynamicModelLoading)
|
||||
ModernFix.LOGGER.info("Baking {}", arg);
|
||||
IExtendedModelBakery extendedBakery = (IExtendedModelBakery)this.field_40571;
|
||||
if(arg instanceof ModelResourceLocation && arg != ModelBakery.MISSING_MODEL_LOCATION) {
|
||||
/* to emulate vanilla model loading, treat as top-level */
|
||||
Optional<Block> blockOpt = Objects.equals(((ModelResourceLocation)arg).getVariant(), "inventory") ? Optional.empty() : BuiltInRegistries.BLOCK.getOptional(new ResourceLocation(arg.getNamespace(), arg.getPath()));
|
||||
if(blockOpt.isPresent()) {
|
||||
/* load via lambda for mods that expect blockstate to get loaded */
|
||||
for(BlockState state : extendedBakery.getBlockStatesForMRL(blockOpt.get().getStateDefinition(), (ModelResourceLocation)arg)) {
|
||||
try {
|
||||
blockStateLoaderHandle.invokeExact(this.field_40571, state);
|
||||
} catch(Throwable e) {
|
||||
ModernFix.LOGGER.error("Error loading model", e);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.field_40571.loadTopLevel((ModelResourceLocation)arg);
|
||||
}
|
||||
cir.setReturnValue(this.field_40571.topLevelModels.getOrDefault(arg, extendedBakery.mfix$getUnbakedMissingModel()));
|
||||
// avoid leaks
|
||||
this.field_40571.topLevelModels.clear();
|
||||
} else
|
||||
cir.setReturnValue(this.field_40571.getModel(arg));
|
||||
if(cir.getReturnValue() == extendedBakery.mfix$getUnbakedMissingModel()) {
|
||||
if(arg != ModelBakery.MISSING_MODEL_LOCATION && debugDynamicModelLoading)
|
||||
ModernFix.LOGGER.warn("Model {} not present", arg);
|
||||
wasMissingModel = true;
|
||||
}
|
||||
cir.getReturnValue().resolveParents(this.field_40571::getModel);
|
||||
}
|
||||
|
||||
@ModifyVariable(method = "bake", at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/client/resources/model/UnbakedModel;bake(Lnet/minecraft/client/resources/model/ModelBaker;Ljava/util/function/Function;Lnet/minecraft/client/resources/model/ModelState;Lnet/minecraft/resources/ResourceLocation;)Lnet/minecraft/client/resources/model/BakedModel;"))
|
||||
private BakedModel unifyMissingBakedModel(BakedModel model) {
|
||||
if(wasMissingModel) {
|
||||
// use a shared baked missing model
|
||||
IExtendedModelBakery extendedBakery = (IExtendedModelBakery)this.field_40571;
|
||||
BakedModel missing;
|
||||
synchronized (this.field_40571) {
|
||||
if(extendedBakery.getBakedMissingModel() == null) {
|
||||
extendedBakery.setBakedMissingModel(model);
|
||||
missing = model;
|
||||
} else {
|
||||
missing = extendedBakery.getBakedMissingModel();
|
||||
}
|
||||
}
|
||||
return missing;
|
||||
}
|
||||
return model;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @author embeddedt
|
||||
* @reason emulate old function, to allow injectors to work
|
||||
*/
|
||||
/*
|
||||
@Overwrite
|
||||
public BakedModel bake(ResourceLocation arg, ModelState arg2) {
|
||||
ModelBakery.BakedCacheKey key = new ModelBakery.BakedCacheKey(arg, arg2.getRotation(), arg2.isUvLocked());
|
||||
BakedModel existing = this.field_40571.bakedCache.get(key);
|
||||
if (existing != null) {
|
||||
cir.setReturnValue(existing);
|
||||
return existing;
|
||||
} else {
|
||||
synchronized (this.field_40571) {
|
||||
if(debugDynamicModelLoading)
|
||||
ModernFix.LOGGER.info("Baking {}", arg);
|
||||
UnbakedModel iunbakedmodel;
|
||||
IExtendedModelBakery extendedBakery = (IExtendedModelBakery)this.field_40571;
|
||||
if(arg instanceof ModelResourceLocation && arg != ModelBakery.MISSING_MODEL_LOCATION) {
|
||||
/* to emulate vanilla model loading, treat as top-level */
|
||||
Optional<Block> blockOpt = BuiltInRegistries.BLOCK.getOptional(new ResourceLocation(arg.getNamespace(), arg.getPath()));
|
||||
if(blockOpt.isPresent()) {
|
||||
/* load via lambda for mods that expect blockstate to get loaded */
|
||||
for(BlockState state : extendedBakery.getBlockStatesForMRL(blockOpt.get().getStateDefinition(), (ModelResourceLocation)arg)) {
|
||||
try {
|
||||
blockStateLoaderHandle.invokeExact(this.field_40571, state);
|
||||
} catch(Throwable e) {
|
||||
ModernFix.LOGGER.error("Error loading model", e);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
this.field_40571.loadTopLevel((ModelResourceLocation)arg);
|
||||
}
|
||||
iunbakedmodel = this.field_40571.topLevelModels.getOrDefault(arg, extendedBakery.mfix$getUnbakedMissingModel());
|
||||
// avoid leaks
|
||||
this.field_40571.topLevelModels.clear();
|
||||
} else
|
||||
iunbakedmodel = this.getModel(arg);
|
||||
if(iunbakedmodel == extendedBakery.mfix$getUnbakedMissingModel() && arg != ModelBakery.MISSING_MODEL_LOCATION && debugDynamicModelLoading)
|
||||
ModernFix.LOGGER.warn("Model {} not present", arg);
|
||||
UnbakedModel iunbakedmodel = this.getModel(arg);
|
||||
// TODO: make sure parent resolution doesn't re-run many times
|
||||
iunbakedmodel.resolveParents(this::getModel);
|
||||
BakedModel ibakedmodel = null;
|
||||
|
|
@ -94,19 +139,21 @@ public abstract class ModelBakerImplMixin {
|
|||
}
|
||||
}
|
||||
if(ibakedmodel == null) {
|
||||
// leave the original assignment in the same spot so wrapping injectors work
|
||||
// this means two bakes might happen for missing models, but not much we can do
|
||||
ibakedmodel = iunbakedmodel.bake((ModelBaker)this, this.modelTextureGetter, arg2, arg);
|
||||
IExtendedModelBakery extendedBakery = (IExtendedModelBakery)this.field_40571;
|
||||
if(iunbakedmodel == extendedBakery.mfix$getUnbakedMissingModel()) {
|
||||
// use a shared baked missing model
|
||||
if(extendedBakery.getBakedMissingModel() == null) {
|
||||
extendedBakery.setBakedMissingModel(iunbakedmodel.bake((ModelBaker)this, this.modelTextureGetter, arg2, arg));
|
||||
((DynamicBakedModelProvider)this.field_40571.getBakedTopLevelModels()).setMissingModel(extendedBakery.getBakedMissingModel());
|
||||
}
|
||||
createBakedMissingModelIfNeeded(extendedBakery, iunbakedmodel, arg2, arg);
|
||||
ibakedmodel = extendedBakery.getBakedMissingModel();
|
||||
} else
|
||||
ibakedmodel = iunbakedmodel.bake((ModelBaker)this, this.modelTextureGetter, arg2, arg);
|
||||
}
|
||||
}
|
||||
this.field_40571.bakedCache.put(key, ibakedmodel);
|
||||
cir.setReturnValue(ibakedmodel);
|
||||
return ibakedmodel;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,17 +31,14 @@ import org.spongepowered.asm.mixin.injection.Redirect;
|
|||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.BiFunction;
|
||||
|
||||
/* high priority so that our injectors are added before other mods' */
|
||||
@Mixin(value = ModelBakery.class, priority = 600)
|
||||
/* low priority so that our injectors are added after other mods' */
|
||||
@Mixin(value = ModelBakery.class, priority = 1100)
|
||||
@ClientOnlyMixin
|
||||
public abstract class ModelBakeryMixin implements IExtendedModelBakery {
|
||||
|
||||
|
|
@ -172,10 +169,14 @@ public abstract class ModelBakeryMixin implements IExtendedModelBakery {
|
|||
|
||||
private BiFunction<ResourceLocation, Material, TextureAtlasSprite> textureGetter;
|
||||
|
||||
@Inject(method = "bakeModels", at = @At("HEAD"), cancellable = true)
|
||||
private void skipBake(BiFunction<ResourceLocation, Material, TextureAtlasSprite> getter, CallbackInfo ci) {
|
||||
@Inject(method = "bakeModels", at = @At("HEAD"))
|
||||
private void captureGetter(BiFunction<ResourceLocation, Material, TextureAtlasSprite> getter, CallbackInfo ci) {
|
||||
textureGetter = getter;
|
||||
ci.cancel();
|
||||
}
|
||||
|
||||
@Redirect(method = "bakeModels", at = @At(value = "INVOKE", target = "Ljava/util/Map;keySet()Ljava/util/Set;"))
|
||||
private Set<ResourceLocation> skipBake(Map<ResourceLocation, UnbakedModel> instance) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -15,3 +15,5 @@ rhino_version=1902.2.2-build.268
|
|||
|
||||
fabric_loader_version=0.14.18
|
||||
fabric_api_version=0.80.0+1.19.4
|
||||
|
||||
continuity_version=3.0.0-beta.2+1.19.3
|
||||
Loading…
Reference in New Issue
Block a user