Skip to content

[1.21.5] Add model loading plugins to replace ModelEvent.ModifyBakingResult #1884

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 6 commits into
base: 1.21.x
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,23 +1,25 @@
--- a/net/minecraft/client/resources/model/ModelBakery.java
+++ b/net/minecraft/client/resources/model/ModelBakery.java
@@ -55,7 +_,12 @@
@@ -55,7 +_,14 @@
private final Map<ResourceLocation, ClientItem> clientInfos;
final Map<ResourceLocation, ResolvedModel> resolvedModels;
final ResolvedModel missingModel;
+ private final net.neoforged.neoforge.client.model.standalone.StandaloneModelLoader.LoadedModels standaloneModels;
+ @org.jetbrains.annotations.Nullable
+ private final net.neoforged.neoforge.client.model.loadingplugin.ModelLoadingPluginManager pluginManager;

+ /**
+ * @deprecated Neo: use {@link #ModelBakery(EntityModelSet, Map, Map, Map, ResolvedModel, net.neoforged.neoforge.client.model.standalone.StandaloneModelLoader.LoadedModels)} instead
+ * @deprecated Neo: use {@link #ModelBakery(EntityModelSet, Map, Map, Map, ResolvedModel, net.neoforged.neoforge.client.model.standalone.StandaloneModelLoader.LoadedModels, net.neoforged.neoforge.client.model.loadingplugin.ModelLoadingPluginManager)} instead
+ */
+ @Deprecated
public ModelBakery(
EntityModelSet p_388903_,
Map<BlockState, BlockStateModel.UnbakedRoot> p_251087_,
@@ -63,11 +_,23 @@
@@ -63,11 +_,25 @@
Map<ResourceLocation, ResolvedModel> p_388404_,
ResolvedModel p_404940_
) {
+ this(p_388903_, p_251087_, p_250416_, p_388404_, p_404940_, net.neoforged.neoforge.client.model.standalone.StandaloneModelLoader.LoadedModels.EMPTY);
+ this(p_388903_, p_251087_, p_250416_, p_388404_, p_404940_, net.neoforged.neoforge.client.model.standalone.StandaloneModelLoader.LoadedModels.EMPTY, null);
+ }
+
+ public ModelBakery(
Expand All @@ -26,17 +28,60 @@
+ Map<ResourceLocation, ClientItem> p_250416_,
+ Map<ResourceLocation, ResolvedModel> p_388404_,
+ ResolvedModel p_404940_,
+ net.neoforged.neoforge.client.model.standalone.StandaloneModelLoader.LoadedModels standaloneModels
+ net.neoforged.neoforge.client.model.standalone.StandaloneModelLoader.LoadedModels standaloneModels,
+ @org.jetbrains.annotations.Nullable net.neoforged.neoforge.client.model.loadingplugin.ModelLoadingPluginManager pluginManager
+ ) {
this.entityModelSet = p_388903_;
this.unbakedBlockStateModels = p_251087_;
this.clientInfos = p_250416_;
this.resolvedModels = p_388404_;
this.missingModel = p_404940_;
+ this.standaloneModels = standaloneModels;
+ this.pluginManager = pluginManager;
}

public CompletableFuture<ModelBakery.BakingResult> bakeModels(SpriteGetter p_404922_, Executor p_405407_) {
@@ -76,7 +_,14 @@
CompletableFuture<Map<BlockState, BlockStateModel>> completablefuture = ParallelMapTransform.schedule(
this.unbakedBlockStateModels, (p_409109_, p_409110_) -> {
try {
- return p_409110_.bake(p_409109_, modelbakery$modelbakerimpl);
+ if (this.pluginManager != null) {
+ p_409110_ = this.pluginManager.modifyBlockModelBeforeBake(p_409109_, p_409110_, modelbakery$modelbakerimpl);
+ }
+ BlockStateModel bakedModel = p_409110_.bake(p_409109_, modelbakery$modelbakerimpl);
+ if (this.pluginManager != null) {
+ bakedModel = this.pluginManager.modifyBlockModelAfterBake(p_409109_, bakedModel, p_409110_, modelbakery$modelbakerimpl);
+ }
+ return bakedModel;
} catch (Exception exception) {
LOGGER.warn("Unable to bake model: '{}': {}", p_409109_, exception);
return null;
@@ -87,12 +_,18 @@
this.clientInfos,
(p_404123_, p_404124_) -> {
try {
- return p_404124_.model()
- .bake(
- new ItemModel.BakingContext(
- modelbakery$modelbakerimpl, this.entityModelSet, modelbakery$missingmodels.item, p_404124_.registrySwapper()
- )
- );
+ ItemModel.BakingContext bakingContext = new ItemModel.BakingContext(
+ modelbakery$modelbakerimpl, this.entityModelSet, modelbakery$missingmodels.item, p_404124_.registrySwapper()
+ );
+ ItemModel.Unbaked unbakedModel = p_404124_.model();
+ if (this.pluginManager != null) {
+ unbakedModel = this.pluginManager.modifyItemModelBeforeBake(p_404123_, unbakedModel, p_404124_, bakingContext);
+ }
+ ItemModel bakedModel = unbakedModel.bake(bakingContext);
+ if (this.pluginManager != null) {
+ bakedModel = this.pluginManager.modifyItemModelAfterBake(p_404123_, bakedModel, unbakedModel, p_404124_, bakingContext);
+ }
+ return bakedModel;
} catch (Exception exception) {
LOGGER.warn("Unable to bake item model: '{}'", p_404123_, exception);
return null;
@@ -100,6 +_,8 @@
},
p_405407_
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
--- a/net/minecraft/client/resources/model/ModelManager.java
+++ b/net/minecraft/client/resources/model/ModelManager.java
@@ -86,11 +_,15 @@
@@ -86,11 +_,16 @@
private int maxMipmapLevels;
private ModelBakery.MissingModels missingModels;
private Object2IntMap<BlockState> modelGroups = Object2IntMaps.emptyMap();
+ private final java.util.concurrent.atomic.AtomicReference<ModelBakery> modelBakery = new java.util.concurrent.atomic.AtomicReference<>(null);
+ private net.neoforged.neoforge.client.model.standalone.StandaloneModelLoader.BakedModels bakedStandaloneModels;
+ private Set<ResourceLocation> reportedMissingItemModels = new java.util.HashSet<>();
+ private volatile CompletableFuture<net.neoforged.neoforge.client.model.loadingplugin.ModelLoadingPluginManager> pluginFuture = CompletableFuture.completedFuture(null);

public ModelManager(TextureManager p_119406_, BlockColors p_119407_, int p_119408_) {
this.blockColors = p_119407_;
Expand All @@ -32,9 +33,17 @@
}

public ClientItem.Properties getItemProperties(ResourceLocation p_390438_) {
@@ -119,8 +_,10 @@
CompletableFuture<Map<ResourceLocation, UnbakedModel>> completablefuture2 = loadBlockModels(p_251134_, p_250550_);
CompletableFuture<BlockStateModelLoader.LoadedModels> completablefuture3 = BlockStateModelLoader.loadBlockStates(p_251134_, p_250550_);
@@ -116,11 +_,16 @@
) {
CompletableFuture<EntityModelSet> completablefuture = CompletableFuture.supplyAsync(EntityModelSet::vanilla, p_250550_);
CompletableFuture<SpecialBlockModelRenderer> completablefuture1 = completablefuture.thenApplyAsync(SpecialBlockModelRenderer::vanilla, p_250550_);
- CompletableFuture<Map<ResourceLocation, UnbakedModel>> completablefuture2 = loadBlockModels(p_251134_, p_250550_);
- CompletableFuture<BlockStateModelLoader.LoadedModels> completablefuture3 = BlockStateModelLoader.loadBlockStates(p_251134_, p_250550_);
+ this.pluginFuture = net.neoforged.neoforge.client.model.loadingplugin.ModelLoadingPluginManager.prepare(p_251134_, p_250550_);
+ CompletableFuture<Map<ResourceLocation, UnbakedModel>> completablefuture2 = loadBlockModels(p_251134_, p_250550_)
+ .thenCombine(this.pluginFuture, (models, pluginManager) -> pluginManager.modifyModelsOnLoad(models));
+ CompletableFuture<BlockStateModelLoader.LoadedModels> completablefuture3 = BlockStateModelLoader.loadBlockStates(p_251134_, p_250550_)
+ .thenCombine(this.pluginFuture, (models, pluginManager) -> pluginManager.modifyBlockModelsOnLoad(models));
CompletableFuture<ClientItemInfoLoader.LoadedClientInfos> completablefuture4 = ClientItemInfoLoader.scheduleLoad(p_251134_, p_250550_);
- CompletableFuture<ModelManager.ResolvedModels> completablefuture5 = CompletableFuture.allOf(completablefuture2, completablefuture3, completablefuture4)
- .thenApplyAsync(p_404152_ -> discoverModelDependencies(completablefuture2.join(), completablefuture3.join(), completablefuture4.join()), p_250550_);
Expand All @@ -45,24 +54,35 @@
CompletableFuture<Object2IntMap<BlockState>> completablefuture6 = completablefuture3.thenApplyAsync(
p_359309_ -> buildModelGroups(this.blockColors, p_359309_), p_250550_
);
@@ -136,6 +_,7 @@
@@ -136,6 +_,8 @@
completablefuture,
completablefuture1,
completablefuture2
+ , standaloneModelsFuture
+ , standaloneModelsFuture,
+ this.pluginFuture
)
)
.toArray(CompletableFuture[]::new)
@@ -156,7 +_,9 @@
@@ -156,12 +_,19 @@
completablefuture4.join().contents(),
modelmanager$resolvedmodels.models(),
modelmanager$resolvedmodels.missing()
+ , standaloneModelsFuture.join()
+ , standaloneModelsFuture.join(),
+ this.pluginFuture.join()
);
+ this.modelBakery.set(modelbakery);
return loadModels(map1, modelbakery, object2intmap, completablefuture.join(), completablefuture1.join(), p_250550_);
},
p_250550_
)
.thenCompose(p_252255_ -> p_252255_.readyForUpload.thenApply(p_251581_ -> (ModelManager.ReloadState)p_252255_))
+ .thenApplyAsync(state -> {
+ this.pluginFuture = CompletableFuture.completedFuture(null);
+ return state;
+ })
.thenCompose(p_249079_::wait)
.thenAcceptAsync(p_372566_ -> this.apply(p_372566_, Profiler.get()), p_249221_);
}
@@ -170,7 +_,7 @@
return CompletableFuture.<Map<ResourceLocation, Resource>>supplyAsync(() -> MODEL_LISTER.listMatchingResources(p_251361_), p_252189_)
.thenCompose(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@
import net.neoforged.neoforge.client.internal.ForgeSnapshotsModClient;
import net.neoforged.neoforge.client.loading.NeoForgeLoadingOverlay;
import net.neoforged.neoforge.client.model.block.BlockStateModelHooks;
import net.neoforged.neoforge.client.model.loadingplugin.ModelLoadingPluginManager;
import net.neoforged.neoforge.client.pipeline.PipelineModifiers;
import net.neoforged.neoforge.client.renderstate.RegisterRenderStateModifiersEvent;
import net.neoforged.neoforge.common.NeoForge;
Expand Down Expand Up @@ -1014,6 +1015,7 @@ public static void initClientHooks(Minecraft mc, ReloadableResourceManager resou
DimensionTransitionScreenManager.init();
RenderPipelines.registerCustomPipelines();
PipelineModifiers.init();
ModelLoadingPluginManager.init();
}

// Runs during Minecraft construction, before initial resource loading and during datagen startup
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@
import net.neoforged.fml.LogicalSide;
import net.neoforged.fml.event.IModBusEvent;
import net.neoforged.neoforge.client.model.UnbakedModelLoader;
import net.neoforged.neoforge.client.model.block.CustomBlockModelDefinition;
import net.neoforged.neoforge.client.model.loadingplugin.ModelLoadingPlugin;
import net.neoforged.neoforge.client.model.loadingplugin.ModelModifier;
import net.neoforged.neoforge.client.model.loadingplugin.PreparableModelLoadingPlugin;
import net.neoforged.neoforge.client.model.standalone.StandaloneModelBaker;
import net.neoforged.neoforge.client.model.standalone.StandaloneModelKey;
import org.jetbrains.annotations.ApiStatus;
Expand All @@ -44,7 +48,10 @@ protected ModelEvent() {}
* <p>This event is not {@linkplain ICancellableEvent cancellable}.</p>
*
* <p>This event is fired on the mod-specific event bus, only on the {@linkplain LogicalSide#CLIENT logical client}.</p>
*
* @deprecated Use {@link CustomBlockModelDefinition}s or {@link ModelModifier}s instead
*/
@Deprecated(forRemoval = true, since = "1.21.5")
public static class ModifyBakingResult extends ModelEvent implements IModBusEvent {
private final ModelBakery.BakingResult bakingResult;
private final Function<Material, TextureAtlasSprite> textureGetter;
Expand Down Expand Up @@ -87,7 +94,7 @@ public ModelBakery getModelBakery() {
* Fired when the {@link ModelManager} is notified of the resource manager reloading.
* Called after the model registry is set up and cached in the {@link net.minecraft.client.renderer.block.BlockModelShaper}.<br>
* The model registry given by this event is unmodifiable. To modify the model registry, use
* {@link ModelEvent.ModifyBakingResult} instead.
* {@link CustomBlockModelDefinition}s or {@link ModelModifier}s instead.
*
* <p>This event is not {@linkplain ICancellableEvent cancellable}.</p>
*
Expand Down Expand Up @@ -182,4 +189,27 @@ public void register(ResourceLocation key, UnbakedModelLoader<?> loader) {
loaders.put(key, loader);
}
}

public static class RegisterLoadingPlugins extends ModelEvent implements IModBusEvent {
private final Map<ResourceLocation, ModelLoadingPlugin> plugins;
private final Map<ResourceLocation, PreparableModelLoadingPlugin<?>> preparablePlugins;

@ApiStatus.Internal
public RegisterLoadingPlugins(Map<ResourceLocation, ModelLoadingPlugin> plugins, Map<ResourceLocation, PreparableModelLoadingPlugin<?>> preparablePlugins) {
this.plugins = plugins;
this.preparablePlugins = preparablePlugins;
}

public void registerPlugin(ResourceLocation id, ModelLoadingPlugin plugin) {
if (plugins.putIfAbsent(id, plugin) != null) {
throw new IllegalStateException("Duplicate ModelLoadingPlugin registration with ID " + id);
}
}

public void registerPlugin(ResourceLocation id, PreparableModelLoadingPlugin<?> plugin) {
if (preparablePlugins.putIfAbsent(id, plugin) != null) {
throw new IllegalStateException("Duplicate PreparableModelLoadingPlugin registration with ID " + id);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
* Copyright (c) NeoForged and contributors
* SPDX-License-Identifier: LGPL-2.1-only
*/

package net.neoforged.neoforge.client.model.loadingplugin;

public interface ModelLoadingPlugin {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could also fold standalone models into the plugin system. (Possibly just deprecating the current API, or rewriting it as a wrapper on top of a plugin).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Of course javadoc is still missing everywhere.

void initialize(Context context);

interface Context {
default void registerModifier(ModelModifier modifier) {
registerModifier(ModelModifier.Phase.DEFAULT, modifier);
}

void registerModifier(ModelModifier.Phase phase, ModelModifier modifier);
}
}
Loading