package slimeknights.tconstruct.library.client.model;
import com.google.common.base.Function;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import net.minecraft.client.renderer.block.model.BakedQuad;
import net.minecraft.client.renderer.block.model.IBakedModel;
import net.minecraft.client.renderer.block.model.ItemCameraTransforms.TransformType;
import net.minecraft.client.renderer.texture.TextureAtlasSprite;
import net.minecraft.client.renderer.vertex.VertexFormat;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.client.model.IModel;
import net.minecraftforge.client.model.IPerspectiveAwareModel;
import net.minecraftforge.client.model.ItemLayerModel;
import net.minecraftforge.client.model.ModelStateComposition;
import net.minecraftforge.common.model.IModelState;
import net.minecraftforge.common.model.TRSRTransformation;
import java.util.Collection;
import java.util.Map;
import javax.vecmath.Vector3f;
import slimeknights.mantle.client.model.BakedSimple;
import slimeknights.tconstruct.library.TinkerRegistry;
import slimeknights.tconstruct.library.client.CustomTextureCreator;
import slimeknights.tconstruct.library.materials.Material;
public class MaterialModel implements IPatternOffset, IModel {
protected final int offsetX;
protected final int offsetY;
private final ImmutableList<ResourceLocation> textures;
public MaterialModel(ImmutableList<ResourceLocation> textures) {
this(textures, 0, 0);
}
public MaterialModel(ImmutableList<ResourceLocation> textures, int offsetX, int offsetY) {
this.textures = textures;
this.offsetX = offsetX;
this.offsetY = offsetY;
}
@Override
public IBakedModel bake(IModelState state, VertexFormat format,
Function<ResourceLocation, TextureAtlasSprite> bakedTextureGetter) {
return bakeIt(state, format, bakedTextureGetter);
}
// the only difference here is the return-type
public BakedMaterialModel bakeIt(IModelState state, VertexFormat format,
Function<ResourceLocation, TextureAtlasSprite> bakedTextureGetter) {
// take offset of texture into account
if(offsetX != 0 || offsetY != 0) {
state = new ModelStateComposition(state, TRSRTransformation
.blockCenterToCorner(new TRSRTransformation(new Vector3f(offsetX / 16f, -offsetY / 16f, 0), null, null, null)));
}
ImmutableMap<TransformType, TRSRTransformation> map = IPerspectiveAwareModel.MapWrapper.getTransforms(state);
// normal model as the base
IBakedModel base = new ItemLayerModel(textures).bake(state, format, bakedTextureGetter);
// turn it into a baked material-model
BakedMaterialModel bakedMaterialModel = new BakedMaterialModel(base, map);
// and generate the baked model for each material-variant we have for the base texture
String baseTexture = base.getParticleTexture().getIconName();
Map<String, TextureAtlasSprite> sprites = CustomTextureCreator.sprites.get(baseTexture);
if(sprites != null) {
for(Map.Entry<String, TextureAtlasSprite> entry : sprites.entrySet()) {
Material material = TinkerRegistry.getMaterial(entry.getKey());
IModel model2 = ItemLayerModel.INSTANCE.retexture(ImmutableMap.of("layer0", entry.getValue().getIconName()));
IBakedModel bakedModel2 = model2.bake(state, format, bakedTextureGetter);
// if it's a colored material we need to color the quads. But only if the texture was not a custom texture
if(material.renderInfo.useVertexColoring() && !CustomTextureCreator.exists(baseTexture + "_" + material.identifier)) {
int color = (material.renderInfo).getVertexColor();
ImmutableList.Builder<BakedQuad> quads = ImmutableList.builder();
// ItemLayerModel.BakedModel only uses general quads
for(BakedQuad quad : bakedModel2.getQuads(null, null, 0)) {
quads.add(ModelHelper.colorQuad(color, quad));
}
// create a new model with the colored quads
bakedModel2 = new BakedSimple(quads.build(), map, bakedModel2);
}
bakedMaterialModel.addMaterialModel(material, bakedModel2);
}
}
return bakedMaterialModel;
}
@Override
public Collection<ResourceLocation> getDependencies() {
return ImmutableList.of();
}
@Override
public Collection<ResourceLocation> getTextures() {
return textures;
}
@Override
public IModelState getDefaultState() {
return ModelHelper.DEFAULT_ITEM_STATE;
}
@Override
public int getXOffset() {
return offsetX;
}
@Override
public int getYOffset() {
return offsetY;
}
}