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.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<UnbakedModel> modifyModelOnLoad(Optional<UnbakedModel> 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);
}
}

View File

@ -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<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) {
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<Block, BlockStateResolver> resolvers = new HashMap<>();
@ -128,5 +256,25 @@ public class FabricDynamicModelHandler implements DynamicModelProvider.DynamicMo
public Event<ModelModifier.OnLoadBlock> modifyBlockModelOnLoad() {
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
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