forked from FabricMC/fabric
Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
8c5c87466f
13 changed files with 687 additions and 3 deletions
|
@ -26,7 +26,7 @@ targetCompatibility = 1.8
|
||||||
|
|
||||||
archivesBaseName = "fabric"
|
archivesBaseName = "fabric"
|
||||||
|
|
||||||
def baseVersion = "0.1.2"
|
def baseVersion = "0.1.3"
|
||||||
def mcVersion = "18w50a"
|
def mcVersion = "18w50a"
|
||||||
|
|
||||||
def ENV = System.getenv()
|
def ENV = System.getenv()
|
||||||
|
@ -38,7 +38,7 @@ minecraft {
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
minecraft "com.mojang:minecraft:$mcVersion"
|
minecraft "com.mojang:minecraft:$mcVersion"
|
||||||
mappings "net.fabricmc:yarn:$mcVersion.59"
|
mappings "net.fabricmc:yarn:$mcVersion.64"
|
||||||
modCompile "net.fabricmc:fabric-loader:0.3.0.74"
|
modCompile "net.fabricmc:fabric-loader:0.3.0.74"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016, 2017, 2018 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 net.minecraft.client.util.ModelIdentifier;
|
||||||
|
import net.minecraft.resource.ResourceManager;
|
||||||
|
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface ModelAppender {
|
||||||
|
void appendAll(ResourceManager manager, Consumer<ModelIdentifier> out);
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016, 2017, 2018 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 net.fabricmc.fabric.impl.client.model.ModelLoadingRegistryImpl;
|
||||||
|
import net.minecraft.resource.ResourceManager;
|
||||||
|
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
public interface ModelLoadingRegistry {
|
||||||
|
ModelLoadingRegistry INSTANCE = ModelLoadingRegistryImpl.INSTANCE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a model appender, which can request loading additional models.
|
||||||
|
*
|
||||||
|
* @param appender
|
||||||
|
*/
|
||||||
|
void registerAppender(ModelAppender appender);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a ModelResourceProvider supplier.
|
||||||
|
*
|
||||||
|
* @param providerSupplier The ModelResourceProvider supplier, instantiated with every ModelLoader.
|
||||||
|
*/
|
||||||
|
void registerResourceProvider(Function<ResourceManager, ModelResourceProvider> providerSupplier);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register a ModelVariantProvider supplier.
|
||||||
|
*
|
||||||
|
* @param providerSupplier The ModelVariantProvider supplier, instantiated with every ModelLoader.
|
||||||
|
*/
|
||||||
|
void registerVariantProvider(Function<ResourceManager, ModelVariantProvider> providerSupplier);
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016, 2017, 2018 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 net.minecraft.client.render.model.UnbakedModel;
|
||||||
|
import net.minecraft.client.util.ModelIdentifier;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The model loading context used during model providing.
|
||||||
|
*/
|
||||||
|
public interface ModelProviderContext {
|
||||||
|
/**
|
||||||
|
* Load a model using a {@link Identifier}, {@link ModelIdentifier}, ...
|
||||||
|
*
|
||||||
|
* Please note that the game engine keeps track of circular model loading calls on its own.
|
||||||
|
*
|
||||||
|
* @param id The model identifier.
|
||||||
|
* @return The UnbakedModel. Can return a missing model if it's not present!
|
||||||
|
*/
|
||||||
|
UnbakedModel loadModel(Identifier id);
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016, 2017, 2018 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;
|
||||||
|
|
||||||
|
public class ModelProviderException extends Exception {
|
||||||
|
public ModelProviderException(String s) {
|
||||||
|
super(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ModelProviderException(String s, Throwable t) {
|
||||||
|
super(s, t);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016, 2017, 2018 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 net.minecraft.client.render.model.UnbakedModel;
|
||||||
|
import net.minecraft.client.util.ModelIdentifier;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for model resource providers.
|
||||||
|
*
|
||||||
|
* Model resource providers hook the loading of model *files* from the resource tree;
|
||||||
|
* that is, in vanilla, it handles going from "minecraft:block/stone" to a
|
||||||
|
* "assets/minecraft/models/block/stone.json" file.
|
||||||
|
*
|
||||||
|
* This is where you want to add your own custom model formats.
|
||||||
|
*
|
||||||
|
* As providers are instantiated with a new provider, it is safe
|
||||||
|
* (and recommended!) to cache information inside a loader.
|
||||||
|
*
|
||||||
|
* Keep in mind that only *one* ModelResourceProvider may respond to a given model
|
||||||
|
* at any time. If you're writing, say, an OBJ loader, this means you could
|
||||||
|
* easily conflict with another OBJ loader unless you take some precautions,
|
||||||
|
* for example:
|
||||||
|
*
|
||||||
|
* a) Only load files with a mod-suffixed name, such as .architect.obj,
|
||||||
|
* b) Only load files from an explicit list of namespaces, registered elsewhere.
|
||||||
|
*/
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface ModelResourceProvider {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param resourceId The resource identifier to be loaded.
|
||||||
|
* @return The loaded UnbakedModel, or null if this ModelResourceProvider doesn't handle a specific Identifier
|
||||||
|
* (or if there was no error!).
|
||||||
|
*/
|
||||||
|
/* @Nullable */ UnbakedModel loadModelResource(Identifier resourceId, ModelProviderContext context) throws ModelProviderException;
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016, 2017, 2018 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 net.minecraft.client.render.model.UnbakedModel;
|
||||||
|
import net.minecraft.client.util.ModelIdentifier;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for model variant providers.
|
||||||
|
*
|
||||||
|
* Model variant providers hook the resolution of ModelIdentifiers. In vanilla, this is
|
||||||
|
* the part where a "minecraft:stone#normal" identifier triggers the loading of a
|
||||||
|
* "minecraft:models/stone" model ({@link ModelResourceProvider} handles the later step).
|
||||||
|
*
|
||||||
|
* The most common use of this is to cooperate with a {@link ModelAppender}, but it can
|
||||||
|
* also allow you to add your own block- or item-state formats. To trigger the loading
|
||||||
|
* of another model, use the passed {@link ModelProviderContext}.
|
||||||
|
*
|
||||||
|
* As every model loading is instantiated with a new provider, it is safe
|
||||||
|
* (and recommended!) to cache information.
|
||||||
|
*
|
||||||
|
* Keep in mind that only *one* ModelVariantProvider may respond to a given model
|
||||||
|
* at any time.
|
||||||
|
*/
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface ModelVariantProvider {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param modelId The model identifier, complete with variant.
|
||||||
|
* @return The loaded UnbakedModel, or null if this ModelVariantProvider doesn't handle a specific Identifier
|
||||||
|
* (or if there was no error!).
|
||||||
|
*/
|
||||||
|
/* @Nullable */ UnbakedModel loadModelVariant(ModelIdentifier modelId, ModelProviderContext context) throws ModelProviderException;
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016, 2017, 2018 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.impl.client.model;
|
||||||
|
|
||||||
|
import net.minecraft.client.render.model.UnbakedModel;
|
||||||
|
import net.minecraft.client.util.ModelIdentifier;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
|
||||||
|
public interface ModelLoaderHooks {
|
||||||
|
public void fabric_addModel(ModelIdentifier id);
|
||||||
|
public UnbakedModel fabric_loadModel(Identifier id);
|
||||||
|
}
|
|
@ -0,0 +1,187 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016, 2017, 2018 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.impl.client.model;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import net.fabricmc.fabric.api.client.model.*;
|
||||||
|
import net.fabricmc.loader.launch.common.FabricLauncherBase;
|
||||||
|
import net.minecraft.client.render.model.ModelLoader;
|
||||||
|
import net.minecraft.client.render.model.UnbakedModel;
|
||||||
|
import net.minecraft.client.util.ModelIdentifier;
|
||||||
|
import net.minecraft.resource.ResourceManager;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
import org.apache.logging.log4j.LogManager;
|
||||||
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class ModelLoadingRegistryImpl implements ModelLoadingRegistry {
|
||||||
|
private static final boolean DEBUG_MODEL_LOADING = FabricLauncherBase.getLauncher().isDevelopment()
|
||||||
|
|| Boolean.valueOf(System.getProperty("fabric.debugModelLoading", "false"));
|
||||||
|
|
||||||
|
@FunctionalInterface
|
||||||
|
private static interface CustomModelItf<T> {
|
||||||
|
UnbakedModel load(T obj) throws ModelProviderException;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class LoaderInstance implements ModelProviderContext {
|
||||||
|
private final Logger logger;
|
||||||
|
private final ResourceManager manager;
|
||||||
|
private final List<ModelVariantProvider> modelVariantProviders;
|
||||||
|
private final List<ModelResourceProvider> modelResourceProviders;
|
||||||
|
private final List<ModelAppender> modelAppenders;
|
||||||
|
private ModelLoader loader;
|
||||||
|
|
||||||
|
private LoaderInstance(ModelLoadingRegistryImpl i, ModelLoader loader, ResourceManager manager) {
|
||||||
|
this.logger = ModelLoadingRegistryImpl.LOGGER;
|
||||||
|
this.loader = loader;
|
||||||
|
this.manager = manager;
|
||||||
|
this.modelVariantProviders = i.variantProviderSuppliers.stream().map((s) -> s.apply(manager)).collect(Collectors.toList());
|
||||||
|
this.modelResourceProviders = i.resourceProviderSuppliers.stream().map((s) -> s.apply(manager)).collect(Collectors.toList());
|
||||||
|
this.modelAppenders = i.appenders;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UnbakedModel loadModel(Identifier id) {
|
||||||
|
if (loader == null) {
|
||||||
|
throw new RuntimeException("Called loadModel too late!");
|
||||||
|
}
|
||||||
|
|
||||||
|
return ((ModelLoaderHooks) loader).fabric_loadModel(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onModelPopulation(Consumer<ModelIdentifier> addModel) {
|
||||||
|
for (ModelAppender appender : modelAppenders) {
|
||||||
|
appender.appendAll(manager, addModel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T> UnbakedModel loadCustomModel(CustomModelItf<T> function, Collection<T> loaders, String debugName) {
|
||||||
|
if (!DEBUG_MODEL_LOADING) {
|
||||||
|
for (T provider : loaders) {
|
||||||
|
try {
|
||||||
|
UnbakedModel model = function.load(provider);
|
||||||
|
if (model != null) {
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
} catch (ModelProviderException e) {
|
||||||
|
logger.error(e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
UnbakedModel modelLoaded = null;
|
||||||
|
T providerUsed = null;
|
||||||
|
List<T> providersApplied = null;
|
||||||
|
|
||||||
|
for (T provider : loaders) {
|
||||||
|
try {
|
||||||
|
UnbakedModel model = function.load(provider);
|
||||||
|
if (model != null) {
|
||||||
|
if (providersApplied != null) {
|
||||||
|
providersApplied.add(provider);
|
||||||
|
} else if (providerUsed != null) {
|
||||||
|
providersApplied = Lists.newArrayList(providerUsed, provider);
|
||||||
|
} else {
|
||||||
|
modelLoaded = model;
|
||||||
|
providerUsed = provider;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (ModelProviderException e) {
|
||||||
|
logger.error(e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (providersApplied != null) {
|
||||||
|
StringBuilder builder = new StringBuilder("Conflict - multiple " + debugName + "s claimed the same unbaked model:");
|
||||||
|
for (T loader : providersApplied) {
|
||||||
|
builder.append("\n\t - ").append(loader.getClass().getName());
|
||||||
|
}
|
||||||
|
logger.error(builder.toString());
|
||||||
|
return null;
|
||||||
|
} else {
|
||||||
|
return modelLoaded;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* @Nullable */
|
||||||
|
public UnbakedModel loadModelFromResource(Identifier resourceId) {
|
||||||
|
return loadCustomModel((r) -> r.loadModelResource(resourceId, this), modelResourceProviders, "resource provider");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* @Nullable */
|
||||||
|
public UnbakedModel loadModelFromVariant(Identifier variantId) {
|
||||||
|
if (!(variantId instanceof ModelIdentifier)) {
|
||||||
|
return loadModelFromResource(variantId);
|
||||||
|
} else {
|
||||||
|
ModelIdentifier modelId = (ModelIdentifier) variantId;
|
||||||
|
UnbakedModel model = loadCustomModel((r) -> r.loadModelVariant((ModelIdentifier) variantId, this), modelVariantProviders, "resource provider");
|
||||||
|
if (model != null) {
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Replicating the special-case from ModelLoader as loadModelFromJson is insufficiently patchable
|
||||||
|
if (Objects.equals(modelId.getVariant(), "inventory")) {
|
||||||
|
Identifier resourceId = new Identifier(modelId.getNamespace(), "item/" + modelId.getPath());
|
||||||
|
model = loadModelFromResource(resourceId);
|
||||||
|
if (model != null) {
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void finish() {
|
||||||
|
loader = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Logger LOGGER = LogManager.getLogger();
|
||||||
|
public static final ModelLoadingRegistryImpl INSTANCE = new ModelLoadingRegistryImpl();
|
||||||
|
|
||||||
|
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<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void registerAppender(ModelAppender appender) {
|
||||||
|
appenders.add(appender);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void registerResourceProvider(Function<ResourceManager, ModelResourceProvider> providerSupplier) {
|
||||||
|
resourceProviderSuppliers.add(providerSupplier);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void registerVariantProvider(Function<ResourceManager, ModelVariantProvider> providerSupplier) {
|
||||||
|
variantProviderSuppliers.add(providerSupplier);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static LoaderInstance begin(ModelLoader loader, ResourceManager manager) {
|
||||||
|
return new LoaderInstance(INSTANCE, loader, manager);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,106 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016, 2017, 2018 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.mixin.client.model;
|
||||||
|
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
|
import net.fabricmc.fabric.impl.client.model.ModelLoaderHooks;
|
||||||
|
import net.fabricmc.fabric.impl.client.model.ModelLoadingRegistryImpl;
|
||||||
|
import net.minecraft.client.render.model.ModelLoader;
|
||||||
|
import net.minecraft.client.render.model.UnbakedModel;
|
||||||
|
import net.minecraft.client.util.ModelIdentifier;
|
||||||
|
import net.minecraft.resource.ResourceManager;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
@Mixin(ModelLoader.class)
|
||||||
|
public class MixinModelLoader implements ModelLoaderHooks {
|
||||||
|
// this is the first one
|
||||||
|
@Shadow
|
||||||
|
public static ModelIdentifier MISSING;
|
||||||
|
@Shadow
|
||||||
|
private ResourceManager resourceContainer;
|
||||||
|
@Shadow
|
||||||
|
private Set<Identifier> field_5390;
|
||||||
|
@Shadow
|
||||||
|
private Map<Identifier, UnbakedModel> unbakedModels;
|
||||||
|
|
||||||
|
private ModelLoadingRegistryImpl.LoaderInstance fabric_mlrLoaderInstance;
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
private void addModel(ModelIdentifier id) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
private void putModel(Identifier id, UnbakedModel unbakedModel) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Shadow
|
||||||
|
private void loadModel(Identifier id) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(at = @At("HEAD"), method = "loadModel", cancellable = true)
|
||||||
|
private void loadModelHook(Identifier id, CallbackInfo ci) {
|
||||||
|
UnbakedModel customModel = fabric_mlrLoaderInstance.loadModelFromVariant(id);
|
||||||
|
if (customModel != null) {
|
||||||
|
putModel(id, customModel);
|
||||||
|
ci.cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(at = @At("HEAD"), method = "addModel")
|
||||||
|
private void addModelHook(ModelIdentifier id, CallbackInfo info) {
|
||||||
|
if (id == MISSING) {
|
||||||
|
//noinspection RedundantCast
|
||||||
|
ModelLoaderHooks hooks = (ModelLoaderHooks) (Object) this;
|
||||||
|
|
||||||
|
fabric_mlrLoaderInstance = ModelLoadingRegistryImpl.begin((ModelLoader) (Object) this, resourceContainer);
|
||||||
|
fabric_mlrLoaderInstance.onModelPopulation(hooks::fabric_addModel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Inject(at = @At("RETURN"), method = "<init>")
|
||||||
|
private void initFinishedHook(CallbackInfo info) {
|
||||||
|
//noinspection ConstantConditions
|
||||||
|
fabric_mlrLoaderInstance.finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void fabric_addModel(ModelIdentifier id) {
|
||||||
|
addModel(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public UnbakedModel fabric_loadModel(Identifier id) {
|
||||||
|
if (!field_5390.add(id)) {
|
||||||
|
throw new IllegalStateException("Circular reference while loading " + id);
|
||||||
|
}
|
||||||
|
loadModel(id);
|
||||||
|
field_5390.remove(id);
|
||||||
|
return unbakedModels.get(id);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"id": "fabric",
|
"id": "fabric",
|
||||||
"name": "Fabric API",
|
"name": "Fabric API",
|
||||||
"version": "0.1.2",
|
"version": "0.1.3",
|
||||||
"side": "universal",
|
"side": "universal",
|
||||||
"description": "Core API module providing key hooks and intercompatibility features.",
|
"description": "Core API module providing key hooks and intercompatibility features.",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
"bugfix.MixinBiomeColors",
|
"bugfix.MixinBiomeColors",
|
||||||
"client.itemgroup.MixinItemGroup",
|
"client.itemgroup.MixinItemGroup",
|
||||||
"client.itemgroup.MixinCreativePlayerInventoryGui",
|
"client.itemgroup.MixinCreativePlayerInventoryGui",
|
||||||
|
"client.model.MixinModelLoader",
|
||||||
"client.render.MixinBlockColorMap",
|
"client.render.MixinBlockColorMap",
|
||||||
"client.render.MixinBlockEntityRenderManager",
|
"client.render.MixinBlockEntityRenderManager",
|
||||||
"client.render.MixinEntityRenderManager",
|
"client.render.MixinEntityRenderManager",
|
||||||
|
|
126
src/test/java/net/fabricmc/fabric/model/ModelModClient.java
Normal file
126
src/test/java/net/fabricmc/fabric/model/ModelModClient.java
Normal file
|
@ -0,0 +1,126 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016, 2017, 2018 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.model;
|
||||||
|
|
||||||
|
import net.fabricmc.api.ClientModInitializer;
|
||||||
|
import net.fabricmc.fabric.api.client.model.ModelLoadingRegistry;
|
||||||
|
import net.fabricmc.fabric.events.client.ClientTickEvent;
|
||||||
|
import net.minecraft.block.BlockState;
|
||||||
|
import net.minecraft.client.MinecraftClient;
|
||||||
|
import net.minecraft.client.render.model.*;
|
||||||
|
import net.minecraft.client.render.model.json.ModelItemPropertyOverrideList;
|
||||||
|
import net.minecraft.client.render.model.json.ModelTransformation;
|
||||||
|
import net.minecraft.client.texture.Sprite;
|
||||||
|
import net.minecraft.client.util.ModelIdentifier;
|
||||||
|
import net.minecraft.util.Identifier;
|
||||||
|
import net.minecraft.util.math.Direction;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
public class ModelModClient implements ClientModInitializer {
|
||||||
|
private static BakedModel bakedModel;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onInitializeClient() {
|
||||||
|
ModelLoadingRegistry.INSTANCE.registerAppender((manager, out) -> {
|
||||||
|
System.out.println("--- ModelAppender called! ---");
|
||||||
|
out.accept(new ModelIdentifier("fabric:model#custom"));
|
||||||
|
});
|
||||||
|
|
||||||
|
ModelLoadingRegistry.INSTANCE.registerVariantProvider(manager -> ((modelId, context) -> {
|
||||||
|
if (modelId.getVariant().equals("custom") && modelId.getNamespace().equals("fabric")) {
|
||||||
|
System.out.println("--- ModelVariantProvider called! ---");
|
||||||
|
return context.loadModel(new Identifier("fabric:custom"));
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
ModelLoadingRegistry.INSTANCE.registerResourceProvider(manager -> ((id, context) -> {
|
||||||
|
if (id.toString().equals("fabric:custom")) {
|
||||||
|
return context.loadModel(new Identifier("fabric:custom2"));
|
||||||
|
} else if (id.toString().equals("fabric:custom2")) {
|
||||||
|
System.out.println("--- ModelResourceProvider called! ---");
|
||||||
|
return new UnbakedModel() {
|
||||||
|
@Override
|
||||||
|
public Collection<Identifier> getModelDependencies() {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<Identifier> getTextureDependencies(Function<Identifier, UnbakedModel> var1, Set<String> var2) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BakedModel bake(ModelLoader var1, Function<Identifier, Sprite> var2, ModelRotationContainer var3) {
|
||||||
|
System.out.println("--- Model baked! ---");
|
||||||
|
|
||||||
|
return bakedModel = new BakedModel() {
|
||||||
|
@Override
|
||||||
|
public List<BakedQuad> getQuads(BlockState var1, Direction var2, Random var3) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean useAmbientOcclusion() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasDepthInGui() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isBuiltin() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Sprite getSprite() {
|
||||||
|
return MinecraftClient.getInstance().getSpriteAtlas().getSprite("missingno");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ModelTransformation getTransformations() {
|
||||||
|
return ModelTransformation.ORIGIN;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ModelItemPropertyOverrideList getItemPropertyOverrides() {
|
||||||
|
return ModelItemPropertyOverrideList.ORIGIN;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
ClientTickEvent.CLIENT.register((client) -> {
|
||||||
|
if (client.getBakedModelManager().getModel(new ModelIdentifier("fabric:model#custom"))
|
||||||
|
== bakedModel && bakedModel != null) {
|
||||||
|
System.out.println("--- MODEL LOADED! ---");
|
||||||
|
} else {
|
||||||
|
System.out.println("--- MODEL NOT LOADED! ---");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue