Provide replacement for ModelAppender that allows loading non-blockstate paths ()

* Extend ModelAppender to allow loading non-blockstate paths

* Use a new interface instead of adding to the old one

* Rename new interface

(cherry picked from commit 6bec8f284f)
This commit is contained in:
Vincent Lee 2020-12-30 10:43:51 -06:00 committed by modmuss50
parent 1d561d2678
commit 7fbd501fc7
6 changed files with 84 additions and 14 deletions
fabric-models-v0/src/main/java/net/fabricmc/fabric

View file

@ -0,0 +1,37 @@
/*
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.fabricmc.fabric.api.client.model;
import java.util.function.Consumer;
import net.minecraft.client.util.ModelIdentifier;
import net.minecraft.resource.ResourceManager;
import net.minecraft.util.Identifier;
@FunctionalInterface
public interface ExtraModelProvider {
/**
* Provides an opportunity inform the game that you would like it to load and bake a model,
* even if that model is not used by any blocks or items.
* @param out Accepts paths to be loaded. Arguments that are {@link ModelIdentifier} will be
* loaded through the blockstate JSON system or, if the variant is {@code inventory}, the item model folder.
* Otherwise, the argument is directly loaded as a JSON.
* For example, <pre>new Identifier("mymod", "foo/bar")</pre> will request loading of the file
* <pre>/assets/mymod/models/foo/bar.json</pre>
*/
void provideExtraModels(ResourceManager manager, Consumer<Identifier> out);
}

View file

@ -20,8 +20,14 @@ import java.util.function.Consumer;
import net.minecraft.client.util.ModelIdentifier;
import net.minecraft.resource.ResourceManager;
import net.minecraft.util.Identifier;
/**
* @deprecated use {@link ExtraModelProvider}, which supports loading of plain {@link Identifier}s
*/
@Deprecated
@FunctionalInterface
public interface ModelAppender {
@Deprecated
void appendAll(ResourceManager manager, Consumer<ModelIdentifier> out);
}

View file

@ -19,6 +19,7 @@ package net.fabricmc.fabric.api.client.model;
import java.util.function.Function;
import net.minecraft.resource.ResourceManager;
import net.minecraft.util.Identifier;
import net.fabricmc.fabric.impl.client.model.ModelLoadingRegistryImpl;
@ -26,10 +27,16 @@ public interface ModelLoadingRegistry {
ModelLoadingRegistry INSTANCE = ModelLoadingRegistryImpl.INSTANCE;
/**
* Register a model appender, which can request loading additional models.
*
* @param appender
* Register a model provider, which can request loading additional models.
* @see ExtraModelProvider
*/
void registerModelProvider(ExtraModelProvider appender);
/**
* Register a model appender, which can request loading additional models.
* @deprecated Use {@link #registerModelProvider(ExtraModelProvider)} instead, which supports loading of plain {@link Identifier}s
*/
@Deprecated
void registerAppender(ModelAppender appender);
/**

View file

@ -17,11 +17,10 @@
package net.fabricmc.fabric.impl.client.model;
import net.minecraft.client.render.model.UnbakedModel;
import net.minecraft.client.util.ModelIdentifier;
import net.minecraft.util.Identifier;
public interface ModelLoaderHooks {
void fabric_addModel(ModelIdentifier id);
void fabric_addModel(Identifier id);
UnbakedModel fabric_loadModel(Identifier id);
}

View file

@ -35,6 +35,7 @@ import net.minecraft.client.util.ModelIdentifier;
import net.minecraft.resource.ResourceManager;
import net.minecraft.util.Identifier;
import net.fabricmc.fabric.api.client.model.ExtraModelProvider;
import net.fabricmc.fabric.api.client.model.ModelAppender;
import net.fabricmc.fabric.api.client.model.ModelLoadingRegistry;
import net.fabricmc.fabric.api.client.model.ModelProviderContext;
@ -57,7 +58,7 @@ public class ModelLoadingRegistryImpl implements ModelLoadingRegistry {
private final ResourceManager manager;
private final List<ModelVariantProvider> modelVariantProviders;
private final List<ModelResourceProvider> modelResourceProviders;
private final List<ModelAppender> modelAppenders;
private final List<ExtraModelProvider> modelAppenders;
private ModelLoader loader;
private LoaderInstance(ModelLoadingRegistryImpl i, ModelLoader loader, ResourceManager manager) {
@ -78,9 +79,9 @@ public class ModelLoadingRegistryImpl implements ModelLoadingRegistry {
return ((ModelLoaderHooks) loader).fabric_loadModel(id);
}
public void onModelPopulation(Consumer<ModelIdentifier> addModel) {
for (ModelAppender appender : modelAppenders) {
appender.appendAll(manager, addModel);
public void onModelPopulation(Consumer<Identifier> addModel) {
for (ExtraModelProvider appender : modelAppenders) {
appender.provideExtraModels(manager, addModel);
}
}
@ -181,11 +182,16 @@ public class ModelLoadingRegistryImpl implements ModelLoadingRegistry {
private final List<Function<ResourceManager, ModelVariantProvider>> variantProviderSuppliers = new ArrayList<>();
private final List<Function<ResourceManager, ModelResourceProvider>> resourceProviderSuppliers = new ArrayList<>();
private final List<ModelAppender> appenders = new ArrayList<>();
private final List<ExtraModelProvider> appenders = new ArrayList<>();
@Override
public void registerModelProvider(ExtraModelProvider appender) {
appenders.add(appender);
}
@Override
public void registerAppender(ModelAppender appender) {
appenders.add(appender);
registerModelProvider((manager, consumer) -> appender.appendAll(manager, consumer::accept));
}
@Override

View file

@ -19,6 +19,7 @@ package net.fabricmc.fabric.mixin.client.model;
import java.util.Map;
import java.util.Set;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
@ -35,7 +36,7 @@ import net.fabricmc.fabric.impl.client.model.ModelLoaderHooks;
import net.fabricmc.fabric.impl.client.model.ModelLoadingRegistryImpl;
@Mixin(ModelLoader.class)
public class MixinModelLoader implements ModelLoaderHooks {
public abstract class MixinModelLoader implements ModelLoaderHooks {
// this is the first one
@Shadow
public static ModelIdentifier MISSING;
@ -45,6 +46,9 @@ public class MixinModelLoader implements ModelLoaderHooks {
private Set<Identifier> modelsToLoad;
@Shadow
private Map<Identifier, UnbakedModel> unbakedModels;
@Shadow
@Final
private Map<Identifier, UnbakedModel> modelsToBake;
private ModelLoadingRegistryImpl.LoaderInstance fabric_mlrLoaderInstance;
@ -57,6 +61,8 @@ public class MixinModelLoader implements ModelLoaderHooks {
@Shadow
private void loadModel(Identifier id) { }
@Shadow public abstract UnbakedModel getOrLoadModel(Identifier id);
@Inject(at = @At("HEAD"), method = "loadModel", cancellable = true)
private void loadModelHook(Identifier id, CallbackInfo ci) {
UnbakedModel customModel = fabric_mlrLoaderInstance.loadModelFromVariant(id);
@ -85,8 +91,17 @@ public class MixinModelLoader implements ModelLoaderHooks {
}
@Override
public void fabric_addModel(ModelIdentifier id) {
addModel(id);
public void fabric_addModel(Identifier id) {
if (id instanceof ModelIdentifier) {
addModel((ModelIdentifier) id);
} else {
// The vanilla addModel method is arbitrarily limited to ModelIdentifiers,
// but it's useful to tell the game to just load and bake a direct model path as well.
// Replicate the vanilla logic of addModel here.
UnbakedModel unbakedModel = getOrLoadModel(id);
this.unbakedModels.put(id, unbakedModel);
this.modelsToBake.put(id, unbakedModel);
}
}
@Override