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 com.google.common.collect.ImmutableSet; import gnu.trove.map.hash.THashMap; import net.minecraft.client.renderer.block.model.IBakedModel; 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.ItemLayerModel; import net.minecraftforge.common.model.IModelState; import net.minecraftforge.common.model.ITransformation; import net.minecraftforge.common.model.TRSRTransformation; import java.util.Collection; import java.util.Map; import javax.vecmath.Vector3f; import slimeknights.tconstruct.library.TinkerRegistry; import slimeknights.tconstruct.library.materials.Material; import slimeknights.tconstruct.library.modifiers.IModifier; /** * This model contains all modifiers for a tool Note that handling may seem confusing, because modifier textures are * loaded on a per-modifier basis, but are translated to a per-tool basis during loading. */ public class ModifierModel implements IModel { private Map<String, String> models = new THashMap<String, String>(); public ModifierModel() { } public void addModelForModifier(String modifier, String texture) { models.put(modifier, texture); } public Map<String, String> getModels() { return models; } @Override public Collection<ResourceLocation> getDependencies() { return ImmutableList.of(); // none } @Override public Collection<ResourceLocation> getTextures() { ImmutableSet.Builder<ResourceLocation> builder = ImmutableSet.builder(); for(String texture : models.values()) { builder.add(new ResourceLocation(texture)); } return builder.build(); } @Override public IBakedModel bake(IModelState state, VertexFormat format, Function<ResourceLocation, TextureAtlasSprite> bakedTextureGetter) { throw new UnsupportedOperationException("The modifier-Model is not built to be used as an item model"); } public Map<String, IBakedModel> bakeModels(IModelState state, VertexFormat format, Function<ResourceLocation, TextureAtlasSprite> bakedTextureGetter) { Map<String, IBakedModel> bakedModels = new THashMap<String, IBakedModel>(); // we scale the modifier up slightly so it's always above the tool float s = 0.025f; ITransformation transformation = new TRSRTransformation(new Vector3f(0, 0, 0.0001f - s / 2f), null, new Vector3f(1, 1, 1f + s), null); for(Map.Entry<String, String> entry : models.entrySet()) { // todo: turn this into an event? // check if the corresponding modifier needs this to be a material model // if this check ever causes an NPE then a modifier has been removed between model loading and model baking IModifier modifier = TinkerRegistry.getModifier(entry.getKey()); if(modifier != null && modifier.hasTexturePerMaterial()) { MaterialModel materialModel = new MaterialModel(ImmutableList.of(new ResourceLocation(entry.getValue()))); BakedMaterialModel bakedModel = materialModel.bakeIt(state, format, bakedTextureGetter); for(Material material : TinkerRegistry.getAllMaterials()) { IBakedModel materialBakedModel = bakedModel.getModelByIdentifier(material.getIdentifier()); if(materialBakedModel != bakedModel) { bakedModels.put(entry.getKey() + material.getIdentifier(), materialBakedModel); } } } else { //ItemCameraTransforms transforms = new ItemCameraTransforms(modelBlock.getThirdPersonTransform(), modelBlock.getFirstPersonTransform(), modelBlock.getHeadTransform(), modelBlock.getInGuiTransform()); //IPerspectiveState perspectiveState = new IPerspectiveState.Impl(state, transforms); IModel model = ItemLayerModel.INSTANCE.retexture(ImmutableMap.of("layer0", entry.getValue())); IBakedModel bakedModel = model.bake(state, format, bakedTextureGetter); bakedModels.put(entry.getKey(), bakedModel); } } return bakedModels; } @Override public IModelState getDefaultState() { return TRSRTransformation.identity(); } }