Support the new Fabric model events

This commit is contained in:
embeddedt 2024-12-24 15:38:33 -05:00
parent 9ed71dcdb4
commit 2f977822df
No known key found for this signature in database
GPG Key ID: A69433EC199B5613
3 changed files with 187 additions and 12 deletions

View File

@ -134,7 +134,7 @@ public class DynamicModelProvider {
this.resourceManager = resourceManager; this.resourceManager = resourceManager;
this.resolver = new DynamicResolver(); this.resolver = new DynamicResolver();
this.itemModelGenerator = new ItemModelGenerator(); this.itemModelGenerator = new ItemModelGenerator();
this.missingModel = this.bakeModel(this.unbakedMissingModel, () -> "missing"); this.missingModel = this.bakeMissingModel();
this.missingItemModel = new MissingItemModel(this.missingModel); this.missingItemModel = new MissingItemModel(this.missingModel);
try { try {
Class.forName("net.fabricmc.fabric.api.client.model.loading.v1.ModelLoadingPlugin"); 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)); 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) { if (DEBUG_DYNAMIC_MODEL_LOADING) {
ModernFix.LOGGER.info("Baking model '{}'", name.get()); ModernFix.LOGGER.info("Baking model '{}'", location);
} }
synchronized (this) { synchronized (this) {
this.resolver.clearResolver(); this.resolver.clearResolver();
model.resolveDependencies(this.resolver); model.resolveDependencies(this.resolver);
var modelBaker = new DynamicBaker(name); var modelBaker = new DynamicBaker(location::toString);
return UnbakedModel.bakeWithTopModelValues(model, modelBaker, BlockModelRotation.X0_Y0); 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) { if (DEBUG_DYNAMIC_MODEL_LOADING) {
ModernFix.LOGGER.info("Baking model '{}'", name.get()); ModernFix.LOGGER.info("Baking model '{}'", mrl);
} }
synchronized (this) { synchronized (this) {
this.resolver.clearResolver(); this.resolver.clearResolver();
model.resolveDependencies(this.resolver); model.resolveDependencies(this.resolver);
var modelBaker = new DynamicBaker(name); var modelBaker = new DynamicBaker(mrl::toString);
return model.bake(modelBaker); 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 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 Optional.of(override);
} }
return this.loadedBlockModels.getUnchecked(location).map(unbakedModel -> { 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 { public interface DynamicModelPlugin {
Optional<UnbakedModel> modifyModelOnLoad(Optional<UnbakedModel> model, ResourceLocation id); Optional<UnbakedModel> modifyModelOnLoad(Optional<UnbakedModel> model, ResourceLocation id);
UnbakedBlockStateModel modifyBlockModelOnLoad(UnbakedBlockStateModel model, ModelResourceLocation id, BlockState state); 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);
} }
} }

View File

@ -7,7 +7,10 @@ import net.fabricmc.fabric.api.event.Event;
import net.fabricmc.fabric.api.event.EventFactory; import net.fabricmc.fabric.api.event.EventFactory;
import net.minecraft.client.renderer.block.BlockModelShaper; import net.minecraft.client.renderer.block.BlockModelShaper;
import net.minecraft.client.renderer.block.model.UnbakedBlockStateModel; 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.ModelResourceLocation;
import net.minecraft.client.resources.model.ModelState;
import net.minecraft.client.resources.model.UnbakedModel; import net.minecraft.client.resources.model.UnbakedModel;
import net.minecraft.resources.ResourceLocation; import net.minecraft.resources.ResourceLocation;
import net.minecraft.world.level.block.Block; import net.minecraft.world.level.block.Block;
@ -51,6 +54,51 @@ public class FabricDynamicModelHandler implements DynamicModelProvider.DynamicMo
return model; return model;
}, MODEL_MODIFIER_PHASES); }, MODEL_MODIFIER_PHASES);
private final Event<ModelModifier.BeforeBakeBlock> 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<ModelModifier.AfterBakeBlock> 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<ModelModifier.BeforeBake> 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<ModelModifier.AfterBake> 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) { public FabricDynamicModelHandler(DynamicModelProvider provider) {
this.pluginList = ModelLoadingPlugin.getAll(); this.pluginList = ModelLoadingPlugin.getAll();
var context = new PluginContext(provider); 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 class PluginContext implements ModelLoadingPlugin.Context {
private final DynamicModelProvider provider; private final DynamicModelProvider provider;
private final Map<Block, BlockStateResolver> resolvers = new HashMap<>(); private final Map<Block, BlockStateResolver> resolvers = new HashMap<>();
@ -128,5 +256,25 @@ public class FabricDynamicModelHandler implements DynamicModelProvider.DynamicMo
public Event<ModelModifier.OnLoadBlock> modifyBlockModelOnLoad() { public Event<ModelModifier.OnLoadBlock> modifyBlockModelOnLoad() {
return onLoadBlockModifiers; return onLoadBlockModifiers;
} }
@Override
public Event<ModelModifier.BeforeBake> modifyModelBeforeBake() {
return beforeBakeModifiers;
}
@Override
public Event<ModelModifier.AfterBake> modifyModelAfterBake() {
return afterBakeModifiers;
}
@Override
public Event<ModelModifier.BeforeBakeBlock> modifyBlockModelBeforeBake() {
return beforeBakeBlockModifiers;
}
@Override
public Event<ModelModifier.AfterBakeBlock> modifyBlockModelAfterBake() {
return afterBakeBlockModifiers;
}
} }
} }

View File

@ -19,7 +19,7 @@ rhino_version=1902.2.2-build.268
supported_minecraft_versions=1.21.4 supported_minecraft_versions=1.21.4
fabric_loader_version=0.16.9 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 continuity_version=3.0.0-beta.4+1.20.2