Do not load models for all of a block's blockstates at once

This commit is contained in:
embeddedt 2024-05-29 20:47:59 -04:00
parent ab8810b7fe
commit d0598055c0
No known key found for this signature in database
GPG Key ID: A69433EC199B5613
3 changed files with 35 additions and 7 deletions

View File

@ -1,9 +1,11 @@
package org.embeddedt.modernfix.common.mixin.perf.dynamic_resources;
import com.google.common.collect.ImmutableList;
import it.unimi.dsi.fastutil.objects.Object2IntMap;
import it.unimi.dsi.fastutil.objects.Object2IntMaps;
import net.minecraft.client.color.block.BlockColors;
import net.minecraft.client.resources.model.BlockStateModelLoader;
import net.minecraft.client.resources.model.ModelResourceLocation;
import net.minecraft.client.resources.model.UnbakedModel;
import net.minecraft.core.DefaultedRegistry;
import net.minecraft.core.registries.BuiltInRegistries;
@ -12,8 +14,10 @@ import net.minecraft.util.profiling.ProfilerFiller;
import net.minecraft.world.level.block.Block;
import net.minecraft.world.level.block.state.BlockState;
import net.minecraft.world.level.block.state.StateDefinition;
import org.embeddedt.modernfix.ModernFix;
import org.embeddedt.modernfix.annotation.ClientOnlyMixin;
import org.embeddedt.modernfix.duck.IBlockStateModelLoader;
import org.embeddedt.modernfix.dynamicresources.ModelBakeryHelpers;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Mutable;
@ -35,16 +39,25 @@ public abstract class BlockStateModelLoaderMixin implements IBlockStateModelLoad
@Shadow @Mutable @Final private Object2IntMap<BlockState> modelGroups;
private ImmutableList<BlockState> filteredStates;
@Inject(method = "<init>", at = @At("RETURN"))
private void makeModelGroupsSynchronized(Map map, ProfilerFiller profilerFiller, UnbakedModel unbakedModel, BlockColors blockColors, BiConsumer biConsumer, CallbackInfo ci) {
this.modelGroups = Object2IntMaps.synchronize(this.modelGroups);
}
@Override
public void loadSpecificBlock(ResourceLocation location) {
var optionalBlock = BuiltInRegistries.BLOCK.getOptional(location);
public void loadSpecificBlock(ModelResourceLocation location) {
var optionalBlock = BuiltInRegistries.BLOCK.getOptional(location.id());
if(optionalBlock.isPresent()) {
this.loadBlockStateDefinitions(location, optionalBlock.get().getStateDefinition());
try {
filteredStates = ModelBakeryHelpers.getBlockStatesForMRL(optionalBlock.get().getStateDefinition(), location);
} catch(RuntimeException e) {
ModernFix.LOGGER.error("Exception filtering states on {}", location, e);
filteredStates = null;
}
this.loadBlockStateDefinitions(location.id(), optionalBlock.get().getStateDefinition());
filteredStates = null;
}
}
@ -52,4 +65,9 @@ public abstract class BlockStateModelLoaderMixin implements IBlockStateModelLoad
private Iterator<?> skipIteratingBlocks(DefaultedRegistry instance) {
return Collections.emptyIterator();
}
@Redirect(method = "loadBlockStateDefinitions", at = @At(value = "INVOKE", target = "Lnet/minecraft/world/level/block/state/StateDefinition;getPossibleStates()Lcom/google/common/collect/ImmutableList;"))
private ImmutableList<BlockState> getFilteredStates(StateDefinition<Block, BlockState> instance) {
return this.filteredStates != null ? this.filteredStates : instance.getPossibleStates();
}
}

View File

@ -53,6 +53,9 @@ public abstract class ModelBakeryMixin implements IExtendedModelBakery {
@Shadow @Final private UnbakedModel missingModel;
@Unique
private static final boolean DEBUG_MODEL_LOADS = Boolean.getBoolean("modernfix.debugDynamicModelLoading");
/**
* Bake a model using the provided texture getter and location. The model is stored in {@link ModelBakeryMixin#bakedTopLevelModels}.
*/
@ -74,10 +77,14 @@ public abstract class ModelBakeryMixin implements IExtendedModelBakery {
private UnbakedModel loadUnbakedModelDynamic(ModelResourceLocation location) {
if(location.equals(MISSING_MODEL_VARIANT)) {
return missingModel;
} else if(location.variant().equals("inventory")) {
}
if(DEBUG_MODEL_LOADS) {
ModernFix.LOGGER.info("Loading model {}", location);
}
if(location.variant().equals("inventory")) {
this.loadItemModelAndDependencies(location.id());
} else {
((IBlockStateModelLoader)dynamicLoader).loadSpecificBlock(location.id());
((IBlockStateModelLoader)dynamicLoader).loadSpecificBlock(location);
}
return this.topLevelModels.getOrDefault(location, this.missingModel);
}
@ -94,6 +101,9 @@ public abstract class ModelBakeryMixin implements IExtendedModelBakery {
if(model == null) {
UnbakedModel prototype = loadUnbakedModelDynamic(location);
prototype.resolveParents(this::getModel);
if(DEBUG_MODEL_LOADS) {
ModernFix.LOGGER.info("Baking model {}", location);
}
this.method_61072(this.textureGetter, location, prototype);
model = bakedTopLevelModels.remove(location);
if(model == null) {

View File

@ -1,7 +1,7 @@
package org.embeddedt.modernfix.duck;
import net.minecraft.resources.ResourceLocation;
import net.minecraft.client.resources.model.ModelResourceLocation;
public interface IBlockStateModelLoader {
void loadSpecificBlock(ResourceLocation location);
void loadSpecificBlock(ModelResourceLocation location);
}