diff --git a/common/src/main/java/org/embeddedt/modernfix/dynamicresources/DynamicModelProvider.java b/common/src/main/java/org/embeddedt/modernfix/dynamicresources/DynamicModelProvider.java index 9b88ff86..5c049430 100644 --- a/common/src/main/java/org/embeddedt/modernfix/dynamicresources/DynamicModelProvider.java +++ b/common/src/main/java/org/embeddedt/modernfix/dynamicresources/DynamicModelProvider.java @@ -134,7 +134,7 @@ public class DynamicModelProvider { this.resourceManager = resourceManager; this.resolver = new DynamicResolver(); this.itemModelGenerator = new ItemModelGenerator(); - this.missingModel = this.bakeModel(this.unbakedMissingModel, () -> "missing"); + this.missingModel = this.bakeMissingModel(); this.missingItemModel = new MissingItemModel(this.missingModel); try { Class.forName("net.fabricmc.fabric.api.client.model.loading.v1.ModelLoadingPlugin"); @@ -372,27 +372,48 @@ public class DynamicModelProvider { return Optional.of(new BlockStateModelLoader.LoadedModels(loadedModels)); } - private BakedModel bakeModel(UnbakedModel model, ModelDebugName name) { + private BakedModel bakeMissingModel() { + this.resolver.clearResolver(); + this.unbakedMissingModel.resolveDependencies(this.resolver); + var modelBaker = new DynamicBaker(() -> "missing"); + return UnbakedModel.bakeWithTopModelValues(this.unbakedMissingModel, modelBaker, BlockModelRotation.X0_Y0); + } + + private BakedModel bakeModel(UnbakedModel model, ResourceLocation location) { if (DEBUG_DYNAMIC_MODEL_LOADING) { - ModernFix.LOGGER.info("Baking model '{}'", name.get()); + ModernFix.LOGGER.info("Baking model '{}'", location); } synchronized (this) { this.resolver.clearResolver(); model.resolveDependencies(this.resolver); - var modelBaker = new DynamicBaker(name); - return UnbakedModel.bakeWithTopModelValues(model, modelBaker, BlockModelRotation.X0_Y0); + var modelBaker = new DynamicBaker(location::toString); + for (var plugin : pluginList) { + model = plugin.modifyModelBeforeBake(model, location, BlockModelRotation.X0_Y0, modelBaker); + } + var bakedModel = UnbakedModel.bakeWithTopModelValues(model, modelBaker, BlockModelRotation.X0_Y0); + for (var plugin : pluginList) { + bakedModel = plugin.modifyModelAfterBake(bakedModel, model, location, BlockModelRotation.X0_Y0, modelBaker); + } + return bakedModel; } } - private BakedModel bakeModel(UnbakedBlockStateModel model, ModelDebugName name) { + private BakedModel bakeModel(UnbakedBlockStateModel model, ModelResourceLocation mrl) { if (DEBUG_DYNAMIC_MODEL_LOADING) { - ModernFix.LOGGER.info("Baking model '{}'", name.get()); + ModernFix.LOGGER.info("Baking model '{}'", mrl); } synchronized (this) { this.resolver.clearResolver(); model.resolveDependencies(this.resolver); - var modelBaker = new DynamicBaker(name); - return model.bake(modelBaker); + var modelBaker = new DynamicBaker(mrl::toString); + for (var plugin : pluginList) { + model = plugin.modifyBlockModelBeforeBake(model, mrl, modelBaker); + } + var bakedModel = model.bake(modelBaker); + for (var plugin : pluginList) { + bakedModel = plugin.modifyBlockModelAfterBake(bakedModel, model, mrl, modelBaker); + } + return bakedModel; } } @@ -417,7 +438,7 @@ public class DynamicModelProvider { }); } return unbakedModelOpt.map(unbakedModel -> { - return this.bakeModel(unbakedModel, location::toString); + return this.bakeModel(unbakedModel, location); }); } } @@ -428,7 +449,7 @@ public class DynamicModelProvider { return Optional.of(override); } return this.loadedBlockModels.getUnchecked(location).map(unbakedModel -> { - return this.bakeModel(unbakedModel, location::toString); + return this.bakeModel(unbakedModel, location); }); } @@ -588,5 +609,11 @@ public class DynamicModelProvider { public interface DynamicModelPlugin { Optional modifyModelOnLoad(Optional model, ResourceLocation id); UnbakedBlockStateModel modifyBlockModelOnLoad(UnbakedBlockStateModel model, ModelResourceLocation id, BlockState state); + + UnbakedModel modifyModelBeforeBake(UnbakedModel model, ResourceLocation id, ModelState state, ModelBaker baker); + BakedModel modifyModelAfterBake(BakedModel bakedModel, UnbakedModel model, ResourceLocation id, ModelState state, ModelBaker baker); + + UnbakedBlockStateModel modifyBlockModelBeforeBake(UnbakedBlockStateModel model, ModelResourceLocation id, ModelBaker baker); + BakedModel modifyBlockModelAfterBake(BakedModel bakedModel, UnbakedBlockStateModel model, ModelResourceLocation id, ModelBaker baker); } } diff --git a/common/src/main/java/org/embeddedt/modernfix/dynamicresources/FabricDynamicModelHandler.java b/common/src/main/java/org/embeddedt/modernfix/dynamicresources/FabricDynamicModelHandler.java index 612ee562..590eb540 100644 --- a/common/src/main/java/org/embeddedt/modernfix/dynamicresources/FabricDynamicModelHandler.java +++ b/common/src/main/java/org/embeddedt/modernfix/dynamicresources/FabricDynamicModelHandler.java @@ -7,7 +7,10 @@ import net.fabricmc.fabric.api.event.Event; import net.fabricmc.fabric.api.event.EventFactory; import net.minecraft.client.renderer.block.BlockModelShaper; import net.minecraft.client.renderer.block.model.UnbakedBlockStateModel; +import net.minecraft.client.resources.model.BakedModel; +import net.minecraft.client.resources.model.ModelBaker; 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 net.minecraft.world.level.block.Block; @@ -51,6 +54,51 @@ public class FabricDynamicModelHandler implements DynamicModelProvider.DynamicMo return model; }, MODEL_MODIFIER_PHASES); + private final Event beforeBakeBlockModifiers = EventFactory.createWithPhases(ModelModifier.BeforeBakeBlock.class, modifiers -> (model, context) -> { + for (ModelModifier.BeforeBakeBlock modifier : modifiers) { + try { + model = modifier.modifyModelBeforeBake(model, context); + } catch (Exception exception) { + ModernFix.LOGGER.error("Failed to modify unbaked block model before bake", exception); + } + } + + return model; + }, MODEL_MODIFIER_PHASES); + private final Event afterBakeBlockModifiers = EventFactory.createWithPhases(ModelModifier.AfterBakeBlock.class, modifiers -> (model, context) -> { + for (ModelModifier.AfterBakeBlock modifier : modifiers) { + try { + model = modifier.modifyModelAfterBake(model, context); + } catch (Exception exception) { + ModernFix.LOGGER.error("Failed to modify baked block model after bake", exception); + } + } + + return model; + }, MODEL_MODIFIER_PHASES); + private final Event beforeBakeModifiers = EventFactory.createWithPhases(ModelModifier.BeforeBake.class, modifiers -> (model, context) -> { + for (ModelModifier.BeforeBake modifier : modifiers) { + try { + model = modifier.modifyModelBeforeBake(model, context); + } catch (Exception exception) { + ModernFix.LOGGER.error("Failed to modify unbaked model before bake", exception); + } + } + + return model; + }, MODEL_MODIFIER_PHASES); + private final Event afterBakeModifiers = EventFactory.createWithPhases(ModelModifier.AfterBake.class, modifiers -> (model, context) -> { + for (ModelModifier.AfterBake modifier : modifiers) { + try { + model = modifier.modifyModelAfterBake(model, context); + } catch (Exception exception) { + ModernFix.LOGGER.error("Failed to modify baked model after bake", exception); + } + } + + return model; + }, MODEL_MODIFIER_PHASES); + public FabricDynamicModelHandler(DynamicModelProvider provider) { this.pluginList = ModelLoadingPlugin.getAll(); var context = new PluginContext(provider); @@ -80,6 +128,86 @@ public class FabricDynamicModelHandler implements DynamicModelProvider.DynamicMo }); } + @Override + public UnbakedModel modifyModelBeforeBake(UnbakedModel model, ResourceLocation id, ModelState state, ModelBaker baker) { + return beforeBakeModifiers.invoker().modifyModelBeforeBake(model, new ModelModifier.BeforeBake.Context() { + @Override + public ResourceLocation id() { + return id; + } + + @Override + public ModelState settings() { + return state; + } + + @Override + public ModelBaker baker() { + return baker; + } + }); + } + + @Override + public BakedModel modifyModelAfterBake(BakedModel bakedModel, UnbakedModel model, ResourceLocation id, ModelState state, ModelBaker baker) { + return afterBakeModifiers.invoker().modifyModelAfterBake(bakedModel, new ModelModifier.AfterBake.Context() { + @Override + public ResourceLocation id() { + return id; + } + + @Override + public UnbakedModel sourceModel() { + return model; + } + + @Override + public ModelState settings() { + return state; + } + + @Override + public ModelBaker baker() { + return baker; + } + }); + } + + @Override + public UnbakedBlockStateModel modifyBlockModelBeforeBake(UnbakedBlockStateModel model, ModelResourceLocation id, ModelBaker baker) { + return beforeBakeBlockModifiers.invoker().modifyModelBeforeBake(model, new ModelModifier.BeforeBakeBlock.Context() { + @Override + public ModelResourceLocation id() { + return id; + } + + @Override + public ModelBaker baker() { + return baker; + } + }); + } + + @Override + public BakedModel modifyBlockModelAfterBake(BakedModel bakedModel, UnbakedBlockStateModel model, ModelResourceLocation id, ModelBaker baker) { + return afterBakeBlockModifiers.invoker().modifyModelAfterBake(bakedModel, new ModelModifier.AfterBakeBlock.Context() { + @Override + public ModelResourceLocation id() { + return id; + } + + @Override + public UnbakedBlockStateModel sourceModel() { + return model; + } + + @Override + public ModelBaker baker() { + return baker; + } + }); + } + private class PluginContext implements ModelLoadingPlugin.Context { private final DynamicModelProvider provider; private final Map resolvers = new HashMap<>(); @@ -128,5 +256,25 @@ public class FabricDynamicModelHandler implements DynamicModelProvider.DynamicMo public Event modifyBlockModelOnLoad() { return onLoadBlockModifiers; } + + @Override + public Event modifyModelBeforeBake() { + return beforeBakeModifiers; + } + + @Override + public Event modifyModelAfterBake() { + return afterBakeModifiers; + } + + @Override + public Event modifyBlockModelBeforeBake() { + return beforeBakeBlockModifiers; + } + + @Override + public Event modifyBlockModelAfterBake() { + return afterBakeBlockModifiers; + } } } diff --git a/gradle.properties b/gradle.properties index 575678b4..44a5a73e 100644 --- a/gradle.properties +++ b/gradle.properties @@ -19,7 +19,7 @@ rhino_version=1902.2.2-build.268 supported_minecraft_versions=1.21.4 fabric_loader_version=0.16.9 -fabric_api_version=0.111.0+1.21.4 +fabric_api_version=0.113.0+1.21.4 continuity_version=3.0.0-beta.4+1.20.2