2014-12-28 04:10:54 +00:00
|
|
|
package net.minecraftforge.client.model;
|
|
|
|
|
2016-03-13 13:16:25 +00:00
|
|
|
import java.util.Deque;
|
2014-12-28 04:10:54 +00:00
|
|
|
import java.util.Map;
|
|
|
|
import java.util.Set;
|
|
|
|
|
|
|
|
import net.minecraft.client.Minecraft;
|
2016-03-01 12:58:03 +00:00
|
|
|
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
|
2016-03-01 20:19:38 +00:00
|
|
|
import net.minecraft.client.resources.IReloadableResourceManager;
|
2014-12-28 04:10:54 +00:00
|
|
|
import net.minecraft.util.ResourceLocation;
|
|
|
|
import net.minecraftforge.client.model.ModelLoader.VanillaLoader;
|
2016-03-13 13:16:25 +00:00
|
|
|
import net.minecraftforge.client.model.ModelLoader.VariantLoader;
|
2015-06-18 11:14:46 +00:00
|
|
|
import net.minecraftforge.client.model.b3d.B3DLoader;
|
2015-07-28 21:23:34 +00:00
|
|
|
import net.minecraftforge.client.model.obj.OBJLoader;
|
2014-12-28 04:10:54 +00:00
|
|
|
import net.minecraftforge.fml.common.FMLLog;
|
|
|
|
|
|
|
|
import org.apache.logging.log4j.Level;
|
|
|
|
|
2016-03-13 13:16:25 +00:00
|
|
|
import com.google.common.base.Joiner;
|
|
|
|
import com.google.common.collect.Maps;
|
|
|
|
import com.google.common.collect.Queues;
|
|
|
|
import com.google.common.collect.Sets;
|
|
|
|
|
2014-12-28 04:10:54 +00:00
|
|
|
/*
|
|
|
|
* Central hub for custom model loaders.
|
|
|
|
*/
|
|
|
|
public class ModelLoaderRegistry
|
|
|
|
{
|
2016-03-13 13:16:25 +00:00
|
|
|
private static final Set<ICustomModelLoader> loaders = Sets.newHashSet();
|
|
|
|
private static final Map<ResourceLocation, IModel> cache = Maps.newHashMap();
|
|
|
|
private static final Deque<ResourceLocation> loadingModels = Queues.newArrayDeque();
|
|
|
|
private static final Set<ResourceLocation> textures = Sets.newHashSet();
|
2014-12-28 04:10:54 +00:00
|
|
|
|
2015-06-18 11:14:46 +00:00
|
|
|
// Forge built-in loaders
|
|
|
|
static
|
|
|
|
{
|
|
|
|
registerLoader(B3DLoader.instance);
|
2015-07-28 21:23:34 +00:00
|
|
|
registerLoader(OBJLoader.instance);
|
2015-06-18 11:14:46 +00:00
|
|
|
registerLoader(ModelFluid.FluidLoader.instance);
|
2015-06-23 01:23:05 +00:00
|
|
|
registerLoader(ItemLayerModel.Loader.instance);
|
2015-12-15 18:49:19 +00:00
|
|
|
registerLoader(MultiLayerModel.Loader.instance);
|
2015-12-15 21:19:04 +00:00
|
|
|
registerLoader(ModelDynBucket.LoaderDynBucket.instance);
|
2015-06-18 11:14:46 +00:00
|
|
|
}
|
|
|
|
|
2014-12-28 04:10:54 +00:00
|
|
|
/*
|
|
|
|
* Makes system aware of your loader.
|
|
|
|
*/
|
|
|
|
public static void registerLoader(ICustomModelLoader loader)
|
|
|
|
{
|
|
|
|
loaders.add(loader);
|
2016-02-10 07:20:13 +00:00
|
|
|
((IReloadableResourceManager) Minecraft.getMinecraft().getResourceManager()).registerReloadListener(loader);
|
2014-12-28 04:10:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
public static boolean loaded(ResourceLocation location)
|
|
|
|
{
|
|
|
|
return cache.containsKey(location);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public static ResourceLocation getActualLocation(ResourceLocation location)
|
|
|
|
{
|
2016-03-13 13:16:25 +00:00
|
|
|
if(location instanceof ModelResourceLocation) return location;
|
2014-12-28 04:10:54 +00:00
|
|
|
if(location.getResourcePath().startsWith("builtin/")) return location;
|
|
|
|
return new ResourceLocation(location.getResourceDomain(), "models/" + location.getResourcePath());
|
|
|
|
}
|
|
|
|
|
2016-01-06 19:00:43 +00:00
|
|
|
/**
|
|
|
|
* Primary method to get IModel instances.
|
|
|
|
* ResourceLocation argument will be passed directly to the custom model loaders,
|
|
|
|
* ModelResourceLocation argument will be loaded through the blockstate system.
|
|
|
|
*/
|
2016-03-13 13:16:25 +00:00
|
|
|
public static IModel getModel(ResourceLocation location)
|
2014-12-28 04:10:54 +00:00
|
|
|
{
|
2016-01-06 19:00:43 +00:00
|
|
|
IModel model;
|
2016-03-13 13:16:25 +00:00
|
|
|
if(cache.containsKey(location)) return cache.get(location);
|
|
|
|
for(ResourceLocation loading : loadingModels)
|
2014-12-28 04:10:54 +00:00
|
|
|
{
|
2016-03-13 13:16:25 +00:00
|
|
|
if(location.getClass() == loading.getClass() && location.equals(loading))
|
2014-12-28 04:10:54 +00:00
|
|
|
{
|
2016-03-13 13:16:25 +00:00
|
|
|
throw new IllegalStateException("circular model dependencies, stack: [" + Joiner.on(", ").join(loadingModels) + "]");
|
2014-12-28 04:10:54 +00:00
|
|
|
}
|
|
|
|
}
|
2016-03-13 13:16:25 +00:00
|
|
|
loadingModels.addLast(location);
|
|
|
|
try
|
2014-12-28 04:10:54 +00:00
|
|
|
{
|
2016-01-06 19:00:43 +00:00
|
|
|
ResourceLocation actual = getActualLocation(location);
|
|
|
|
ICustomModelLoader accepted = null;
|
|
|
|
for(ICustomModelLoader loader : loaders)
|
2015-06-16 23:03:10 +00:00
|
|
|
{
|
2016-01-06 19:00:43 +00:00
|
|
|
try
|
|
|
|
{
|
|
|
|
if(loader.accepts(actual))
|
|
|
|
{
|
|
|
|
if(accepted != null)
|
|
|
|
{
|
|
|
|
FMLLog.severe("2 loaders (%s and %s) want to load the same model %s", accepted, loader, location);
|
|
|
|
throw new IllegalStateException("2 loaders want to load the same model");
|
|
|
|
}
|
|
|
|
accepted = loader;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
catch(Exception e)
|
|
|
|
{
|
|
|
|
FMLLog.log(Level.ERROR, e, "Exception checking if model %s can be loaded with loader %s, skipping", location, loader);
|
|
|
|
}
|
2015-06-16 23:03:10 +00:00
|
|
|
}
|
2016-01-06 19:00:43 +00:00
|
|
|
|
2016-03-13 13:16:25 +00:00
|
|
|
// no custom loaders found, try vanilla ones
|
2016-01-06 19:00:43 +00:00
|
|
|
if(accepted == null)
|
2015-06-16 23:03:10 +00:00
|
|
|
{
|
2016-03-13 13:16:25 +00:00
|
|
|
if(VariantLoader.instance.accepts(actual))
|
|
|
|
{
|
|
|
|
accepted = VariantLoader.instance;
|
|
|
|
}
|
|
|
|
else if(VanillaLoader.instance.accepts(actual))
|
|
|
|
{
|
|
|
|
accepted = VanillaLoader.instance;
|
|
|
|
}
|
2015-06-16 23:03:10 +00:00
|
|
|
}
|
2016-01-06 19:00:43 +00:00
|
|
|
|
|
|
|
if(accepted == null)
|
2015-06-16 23:03:10 +00:00
|
|
|
{
|
2016-01-06 19:00:43 +00:00
|
|
|
FMLLog.severe("no suitable loader found for the model %s, skipping", location);
|
2015-06-16 23:03:10 +00:00
|
|
|
model = getMissingModel();
|
|
|
|
}
|
2016-01-06 19:00:43 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
model = accepted.loadModel(actual);
|
|
|
|
}
|
|
|
|
catch(Exception e)
|
|
|
|
{
|
|
|
|
FMLLog.log(Level.ERROR, e, "Exception loading model %s with loader %s, skipping", location, accepted);
|
|
|
|
model = getMissingModel();
|
|
|
|
}
|
2016-03-13 13:16:25 +00:00
|
|
|
if(model == getMissingModel())
|
|
|
|
{
|
|
|
|
FMLLog.log(Level.ERROR, "Loader %s returned missing model while loading model %s", accepted, location);
|
|
|
|
}
|
|
|
|
if(model == null)
|
|
|
|
{
|
|
|
|
FMLLog.log(Level.ERROR, "Loader %s returned null while loading model %s", accepted, location);
|
|
|
|
model = getMissingModel();
|
|
|
|
}
|
|
|
|
textures.addAll(model.getTextures());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
finally
|
|
|
|
{
|
|
|
|
ResourceLocation popLoc = loadingModels.removeLast();
|
|
|
|
if(popLoc != location)
|
|
|
|
{
|
|
|
|
throw new IllegalStateException("Corrupted loading model stack: " + popLoc + " != " + location);
|
2016-01-06 19:00:43 +00:00
|
|
|
}
|
2014-12-28 04:10:54 +00:00
|
|
|
}
|
|
|
|
cache.put(location, model);
|
2016-03-13 13:16:25 +00:00
|
|
|
for (ResourceLocation dep : model.getDependencies())
|
|
|
|
{
|
|
|
|
getModel(dep);
|
|
|
|
}
|
2014-12-28 04:10:54 +00:00
|
|
|
return model;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static IModel getMissingModel()
|
|
|
|
{
|
|
|
|
return ModelLoader.VanillaLoader.instance.getLoader().getMissingModel();
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void clearModelCache()
|
|
|
|
{
|
|
|
|
cache.clear();
|
2015-10-27 15:34:25 +00:00
|
|
|
// putting the builtin models in
|
|
|
|
cache.put(new ResourceLocation("minecraft:builtin/generated"), ModelLoader.VanillaLoader.instance.getLoader().getItemModel());
|
|
|
|
cache.put(new ResourceLocation("minecraft:block/builtin/generated"), ModelLoader.VanillaLoader.instance.getLoader().getItemModel());
|
|
|
|
cache.put(new ResourceLocation("minecraft:item/builtin/generated"), ModelLoader.VanillaLoader.instance.getLoader().getItemModel());
|
2014-12-28 04:10:54 +00:00
|
|
|
}
|
2016-03-13 13:16:25 +00:00
|
|
|
|
|
|
|
static Iterable<ResourceLocation> getTextures()
|
|
|
|
{
|
|
|
|
return textures;
|
|
|
|
}
|
2014-12-28 04:10:54 +00:00
|
|
|
}
|