2016-06-23 03:49:47 +00:00
|
|
|
/*
|
|
|
|
* Minecraft Forge
|
|
|
|
* Copyright (c) 2016.
|
|
|
|
*
|
|
|
|
* This library is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
|
|
* License as published by the Free Software Foundation version 2.1
|
|
|
|
* of the License.
|
|
|
|
*
|
|
|
|
* This library is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
* Lesser General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
|
|
* License along with this library; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
*/
|
|
|
|
|
2015-12-15 18:49:19 +00:00
|
|
|
package net.minecraftforge.client.model;
|
|
|
|
|
|
|
|
import java.util.Collection;
|
|
|
|
import java.util.List;
|
|
|
|
|
2017-01-11 23:17:56 +00:00
|
|
|
import javax.annotation.Nonnull;
|
2015-12-15 18:49:19 +00:00
|
|
|
import javax.vecmath.Matrix4f;
|
|
|
|
|
|
|
|
import net.minecraft.block.state.IBlockState;
|
|
|
|
import net.minecraft.client.renderer.block.model.BakedQuad;
|
2016-03-01 20:19:38 +00:00
|
|
|
import net.minecraft.client.renderer.block.model.IBakedModel;
|
2015-12-15 18:49:19 +00:00
|
|
|
import net.minecraft.client.renderer.block.model.ItemCameraTransforms;
|
|
|
|
import net.minecraft.client.renderer.block.model.ItemCameraTransforms.TransformType;
|
2016-03-01 20:19:38 +00:00
|
|
|
import net.minecraft.client.renderer.block.model.ItemOverrideList;
|
|
|
|
import net.minecraft.client.renderer.block.model.ModelResourceLocation;
|
2015-12-15 18:49:19 +00:00
|
|
|
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
|
|
|
|
import net.minecraft.client.renderer.vertex.VertexFormat;
|
|
|
|
import net.minecraft.client.resources.IResourceManager;
|
2016-03-01 12:58:03 +00:00
|
|
|
import net.minecraft.util.BlockRenderLayer;
|
2016-03-01 20:19:38 +00:00
|
|
|
import net.minecraft.util.EnumFacing;
|
2015-12-15 18:49:19 +00:00
|
|
|
import net.minecraft.util.ResourceLocation;
|
|
|
|
import net.minecraftforge.client.MinecraftForgeClient;
|
2016-12-17 21:23:39 +00:00
|
|
|
import net.minecraftforge.common.ForgeVersion;
|
2016-03-21 07:01:30 +00:00
|
|
|
import net.minecraftforge.common.model.IModelState;
|
|
|
|
import net.minecraftforge.common.model.TRSRTransformation;
|
2015-12-15 18:49:19 +00:00
|
|
|
import net.minecraftforge.fml.common.FMLLog;
|
|
|
|
|
2015-12-30 04:15:03 +00:00
|
|
|
import org.apache.commons.lang3.tuple.Pair;
|
|
|
|
|
2015-12-15 18:49:19 +00:00
|
|
|
import com.google.common.base.Function;
|
|
|
|
import com.google.common.base.Optional;
|
|
|
|
import com.google.common.collect.ImmutableList;
|
|
|
|
import com.google.common.collect.ImmutableMap;
|
|
|
|
import com.google.gson.JsonElement;
|
|
|
|
import com.google.gson.JsonParser;
|
|
|
|
|
2016-03-15 22:42:01 +00:00
|
|
|
public final class MultiLayerModel implements IModelCustomData
|
2015-12-15 18:49:19 +00:00
|
|
|
{
|
2016-03-21 07:23:27 +00:00
|
|
|
public static final MultiLayerModel INSTANCE = new MultiLayerModel(ImmutableMap.<Optional<BlockRenderLayer>, ModelResourceLocation>of());
|
2015-12-15 18:49:19 +00:00
|
|
|
|
2016-03-01 12:58:03 +00:00
|
|
|
private final ImmutableMap<Optional<BlockRenderLayer>, ModelResourceLocation> models;
|
2015-12-15 18:49:19 +00:00
|
|
|
|
2016-03-01 12:58:03 +00:00
|
|
|
public MultiLayerModel(ImmutableMap<Optional<BlockRenderLayer>, ModelResourceLocation> models)
|
2015-12-15 18:49:19 +00:00
|
|
|
{
|
|
|
|
this.models = models;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public Collection<ResourceLocation> getDependencies()
|
|
|
|
{
|
|
|
|
return ImmutableList.<ResourceLocation>copyOf(models.values());
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public Collection<ResourceLocation> getTextures()
|
|
|
|
{
|
|
|
|
return ImmutableList.of();
|
|
|
|
}
|
|
|
|
|
2016-03-01 20:19:38 +00:00
|
|
|
private static ImmutableMap<Optional<BlockRenderLayer>, IBakedModel> buildModels(ImmutableMap<Optional<BlockRenderLayer>, ModelResourceLocation> models, IModelState state, VertexFormat format, Function<ResourceLocation, TextureAtlasSprite> bakedTextureGetter)
|
2016-01-06 19:00:43 +00:00
|
|
|
{
|
2016-03-01 20:19:38 +00:00
|
|
|
ImmutableMap.Builder<Optional<BlockRenderLayer>, IBakedModel> builder = ImmutableMap.builder();
|
2016-03-01 12:58:03 +00:00
|
|
|
for(Optional<BlockRenderLayer> key : models.keySet())
|
2016-01-06 19:00:43 +00:00
|
|
|
{
|
2016-03-15 22:42:01 +00:00
|
|
|
IModel model = ModelLoaderRegistry.getModelOrLogError(models.get(key), "Couldn't load MultiLayerModel dependency: " + models.get(key));
|
2016-01-06 19:00:43 +00:00
|
|
|
builder.put(key, model.bake(new ModelStateComposition(state, model.getDefaultState()), format, bakedTextureGetter));
|
|
|
|
}
|
|
|
|
return builder.build();
|
|
|
|
}
|
|
|
|
|
2015-12-15 18:49:19 +00:00
|
|
|
@Override
|
2016-03-01 20:19:38 +00:00
|
|
|
public IBakedModel bake(IModelState state, VertexFormat format, Function<ResourceLocation, TextureAtlasSprite> bakedTextureGetter)
|
2015-12-15 18:49:19 +00:00
|
|
|
{
|
2016-01-06 19:00:43 +00:00
|
|
|
IModel missing = ModelLoaderRegistry.getMissingModel();
|
|
|
|
return new MultiLayerBakedModel(
|
|
|
|
buildModels(models, state, format, bakedTextureGetter),
|
|
|
|
missing.bake(missing.getDefaultState(), format, bakedTextureGetter),
|
|
|
|
IPerspectiveAwareModel.MapWrapper.getTransforms(state)
|
|
|
|
);
|
2015-12-15 18:49:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public IModelState getDefaultState()
|
|
|
|
{
|
|
|
|
return TRSRTransformation.identity();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2016-03-02 17:00:32 +00:00
|
|
|
public MultiLayerModel process(ImmutableMap<String, String> customData)
|
2015-12-15 18:49:19 +00:00
|
|
|
{
|
2016-03-01 12:58:03 +00:00
|
|
|
ImmutableMap.Builder<Optional<BlockRenderLayer>, ModelResourceLocation> builder = ImmutableMap.builder();
|
2015-12-15 18:49:19 +00:00
|
|
|
for(String key : customData.keySet())
|
|
|
|
{
|
|
|
|
if("base".equals(key))
|
|
|
|
{
|
2016-03-01 12:58:03 +00:00
|
|
|
builder.put(Optional.<BlockRenderLayer>absent(), getLocation(customData.get(key)));
|
2015-12-15 18:49:19 +00:00
|
|
|
}
|
2016-03-01 12:58:03 +00:00
|
|
|
for(BlockRenderLayer layer : BlockRenderLayer.values())
|
2015-12-15 18:49:19 +00:00
|
|
|
{
|
|
|
|
if(layer.toString().equals(key))
|
|
|
|
{
|
|
|
|
builder.put(Optional.of(layer), getLocation(customData.get(key)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-03-01 12:58:03 +00:00
|
|
|
ImmutableMap<Optional<BlockRenderLayer>, ModelResourceLocation> models = builder.build();
|
2016-03-21 07:23:27 +00:00
|
|
|
if(models.isEmpty()) return INSTANCE;
|
2015-12-15 18:49:19 +00:00
|
|
|
return new MultiLayerModel(models);
|
|
|
|
}
|
|
|
|
|
|
|
|
private ModelResourceLocation getLocation(String json)
|
|
|
|
{
|
|
|
|
JsonElement e = new JsonParser().parse(json);
|
|
|
|
if(e.isJsonPrimitive() && e.getAsJsonPrimitive().isString())
|
|
|
|
{
|
|
|
|
return new ModelResourceLocation(e.getAsString());
|
|
|
|
}
|
2017-06-23 05:33:11 +00:00
|
|
|
FMLLog.log.fatal("Expect ModelResourceLocation, got: {}", json);
|
2015-12-15 18:49:19 +00:00
|
|
|
return new ModelResourceLocation("builtin/missing", "missing");
|
|
|
|
}
|
|
|
|
|
2016-03-15 22:42:01 +00:00
|
|
|
private static final class MultiLayerBakedModel implements IPerspectiveAwareModel
|
2015-12-15 18:49:19 +00:00
|
|
|
{
|
2016-03-01 20:19:38 +00:00
|
|
|
private final ImmutableMap<Optional<BlockRenderLayer>, IBakedModel> models;
|
2015-12-15 18:49:19 +00:00
|
|
|
private final ImmutableMap<TransformType, TRSRTransformation> cameraTransforms;;
|
2016-03-01 20:19:38 +00:00
|
|
|
private final IBakedModel base;
|
|
|
|
private final IBakedModel missing;
|
2016-01-06 19:00:43 +00:00
|
|
|
private final ImmutableMap<Optional<EnumFacing>, ImmutableList<BakedQuad>> quads;
|
2015-12-15 18:49:19 +00:00
|
|
|
|
2016-03-01 20:19:38 +00:00
|
|
|
public MultiLayerBakedModel(ImmutableMap<Optional<BlockRenderLayer>, IBakedModel> models, IBakedModel missing, ImmutableMap<TransformType, TRSRTransformation> cameraTransforms)
|
2015-12-15 18:49:19 +00:00
|
|
|
{
|
2016-01-06 19:00:43 +00:00
|
|
|
this.models = models;
|
|
|
|
this.cameraTransforms = cameraTransforms;
|
|
|
|
this.missing = missing;
|
|
|
|
if(models.containsKey(Optional.absent()))
|
2015-12-15 18:49:19 +00:00
|
|
|
{
|
2016-01-06 19:00:43 +00:00
|
|
|
base = models.get(Optional.absent());
|
2015-12-15 18:49:19 +00:00
|
|
|
}
|
2016-01-06 19:00:43 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
base = missing;
|
|
|
|
}
|
|
|
|
ImmutableMap.Builder<Optional<EnumFacing>, ImmutableList<BakedQuad>> quadBuilder = ImmutableMap.builder();
|
|
|
|
quadBuilder.put(Optional.<EnumFacing>absent(), buildQuads(models, Optional.<EnumFacing>absent()));
|
|
|
|
for(EnumFacing side: EnumFacing.values())
|
2015-12-15 18:49:19 +00:00
|
|
|
{
|
2016-01-06 19:00:43 +00:00
|
|
|
quadBuilder.put(Optional.of(side), buildQuads(models, Optional.of(side)));
|
2015-12-15 18:49:19 +00:00
|
|
|
}
|
2016-01-06 19:00:43 +00:00
|
|
|
quads = quadBuilder.build();
|
2015-12-15 18:49:19 +00:00
|
|
|
}
|
|
|
|
|
2016-03-01 20:19:38 +00:00
|
|
|
private static ImmutableList<BakedQuad> buildQuads(ImmutableMap<Optional<BlockRenderLayer>, IBakedModel> models, Optional<EnumFacing> side)
|
2015-12-15 18:49:19 +00:00
|
|
|
{
|
|
|
|
ImmutableList.Builder<BakedQuad> builder = ImmutableList.builder();
|
2016-01-06 19:00:43 +00:00
|
|
|
for(IBakedModel model : models.values())
|
2015-12-15 18:49:19 +00:00
|
|
|
{
|
2016-03-13 01:40:03 +00:00
|
|
|
builder.addAll(model.getQuads(null, side.orNull(), 0));
|
2015-12-15 18:49:19 +00:00
|
|
|
}
|
|
|
|
return builder.build();
|
|
|
|
}
|
|
|
|
|
2017-01-11 23:17:56 +00:00
|
|
|
@Nonnull
|
2015-12-15 18:49:19 +00:00
|
|
|
@Override
|
2016-03-13 01:40:03 +00:00
|
|
|
public List<BakedQuad> getQuads(IBlockState state, EnumFacing side, long rand)
|
2015-12-15 18:49:19 +00:00
|
|
|
{
|
2016-03-01 20:19:38 +00:00
|
|
|
IBakedModel model;
|
|
|
|
BlockRenderLayer layer = MinecraftForgeClient.getRenderLayer();
|
|
|
|
if(layer == null)
|
|
|
|
{
|
|
|
|
return quads.get(Optional.fromNullable(side));
|
|
|
|
}
|
2016-03-17 04:28:19 +00:00
|
|
|
else if(!models.containsKey(Optional.of(layer)))
|
2016-03-01 20:19:38 +00:00
|
|
|
{
|
|
|
|
model = missing;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
model = models.get(Optional.of(layer));
|
|
|
|
}
|
2016-03-17 04:28:19 +00:00
|
|
|
// assumes that child model will handle this state properly. FIXME?
|
2016-03-13 01:40:03 +00:00
|
|
|
return model.getQuads(state, side, rand);
|
2015-12-15 18:49:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean isAmbientOcclusion()
|
|
|
|
{
|
|
|
|
return base.isAmbientOcclusion();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean isGui3d()
|
|
|
|
{
|
|
|
|
return base.isGui3d();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2016-03-13 01:40:03 +00:00
|
|
|
public boolean isBuiltInRenderer()
|
2015-12-15 18:49:19 +00:00
|
|
|
{
|
2016-03-13 01:40:03 +00:00
|
|
|
return base.isBuiltInRenderer();
|
2015-12-15 18:49:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2015-12-30 04:15:03 +00:00
|
|
|
public TextureAtlasSprite getParticleTexture()
|
2015-12-15 18:49:19 +00:00
|
|
|
{
|
2015-12-30 04:15:03 +00:00
|
|
|
return base.getParticleTexture();
|
2015-12-15 18:49:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public ItemCameraTransforms getItemCameraTransforms()
|
|
|
|
{
|
|
|
|
return ItemCameraTransforms.DEFAULT;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2016-03-01 20:19:38 +00:00
|
|
|
public Pair<? extends IBakedModel, Matrix4f> handlePerspective(TransformType cameraTransformType)
|
2015-12-15 18:49:19 +00:00
|
|
|
{
|
2016-03-01 20:19:38 +00:00
|
|
|
return IPerspectiveAwareModel.MapWrapper.handlePerspective(this, cameraTransforms, cameraTransformType);
|
2015-12-15 18:49:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2016-03-13 01:40:03 +00:00
|
|
|
public ItemOverrideList getOverrides()
|
2015-12-15 18:49:19 +00:00
|
|
|
{
|
2016-03-13 01:40:03 +00:00
|
|
|
return ItemOverrideList.NONE;
|
2015-12-15 18:49:19 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public static enum Loader implements ICustomModelLoader
|
|
|
|
{
|
2016-03-21 07:23:27 +00:00
|
|
|
INSTANCE;
|
2015-12-15 18:49:19 +00:00
|
|
|
|
2017-06-18 01:24:17 +00:00
|
|
|
@Override
|
2015-12-15 18:49:19 +00:00
|
|
|
public void onResourceManagerReload(IResourceManager resourceManager) {}
|
|
|
|
|
2017-06-18 01:24:17 +00:00
|
|
|
@Override
|
2015-12-15 18:49:19 +00:00
|
|
|
public boolean accepts(ResourceLocation modelLocation)
|
|
|
|
{
|
2016-12-17 21:23:39 +00:00
|
|
|
return modelLocation.getResourceDomain().equals(ForgeVersion.MOD_ID) && (
|
2015-12-15 18:49:19 +00:00
|
|
|
modelLocation.getResourcePath().equals("multi-layer") ||
|
|
|
|
modelLocation.getResourcePath().equals("models/block/multi-layer") ||
|
|
|
|
modelLocation.getResourcePath().equals("models/item/multi-layer"));
|
|
|
|
}
|
|
|
|
|
2017-06-18 01:24:17 +00:00
|
|
|
@Override
|
2015-12-15 18:49:19 +00:00
|
|
|
public IModel loadModel(ResourceLocation modelLocation)
|
|
|
|
{
|
2016-03-21 07:23:27 +00:00
|
|
|
return MultiLayerModel.INSTANCE;
|
2015-12-15 18:49:19 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|