/**
* Copyright (c) Lambda Innovation, 2013-2015
* 本作品版权由Lambda Innovation所有。
* http://www.li-dev.cn/
*
* This project is open-source, and it is distributed under
* the terms of GNU General Public License. You can modify
* and distribute freely as long as you follow the license.
* 本项目是一个开源项目,且遵循GNU通用公共授权协议。
* 在遵照该协议的情况下,您可以自由传播和修改。
* http://www.gnu.org/licenses/gpl.html
*/
package cn.liutils.template.client.render.item;
import java.util.Random;
import javax.vecmath.Vector2d;
import net.minecraft.client.Minecraft;
import net.minecraft.client.renderer.RenderBlocks;
import net.minecraft.client.renderer.Tessellator;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.Vec3;
import net.minecraftforge.client.IItemRenderer;
import org.lwjgl.opengl.GL11;
import cn.liutils.api.render.model.IItemModel;
import cn.liutils.util.client.RenderUtils;
import cn.liutils.util.helper.GameTimer;
import cpw.mods.fml.relauncher.Side;
import cpw.mods.fml.relauncher.SideOnly;
/**
* Item model render. Implemented lots of methods to adjust rendering and positioning.
*/
@SideOnly(Side.CLIENT)
public class RenderModelItem implements IItemRenderer {
protected Tessellator t = Tessellator.instance;
protected Minecraft mc = Minecraft.getMinecraft();
protected static Random RNG = new Random();
/**
* The target rendering model.
*/
IItemModel model;
/**
* Default binding texture.
*/
ResourceLocation texturePath;
/**
* About TRANSFORMATION:
* The transform process goes like : Standard-> Sub
* Within one transform goes like : Scale -> Rotation -> Transformation
* For example, when rendering EQUIPPING:
* StdScale->Std Rotation->Std Offset->Equip Scale->Equip Rotation->Equip Offset
*/
/**
* Standard Rotation.
*/
public Vec3 stdRotation = initVec();
/**
* Standard Offset.
*/
public Vec3 stdOffset = initVec();
/**
* Standard Scale.
*/
public double scale = 1.0;
public double equipScale = 1.0;
public double thirdPersonScale = 1.0;
public double entityItemScale = 1.0;
/**
* Equip Offset
*/
public Vec3 equipOffset = initVec();
public Vec3 thirdPersonOffset = initVec();
/**
* Equip Rotation
*/
public Vec3 equipRotation = initVec();
/**
* Inventory Scale
*/
public double invScale = 1.0F;
/**
* Inventory Offset
*/
public Vector2d invOffset = new Vector2d();
/**
* Inventory Rotation
*/
public Vec3 invRotation = initVec();
/**
* Entity Item Rotation.
*/
public Vec3 entityItemRotation = initVec();
/**
* Handle render Inventory or not
*/
public boolean renderInventory = true;
/**
* Handle render EntityItem or not
*/
public boolean renderEntityItem = true;
/**
* Spin item all the time insides the inventory?
*/
public boolean inventorySpin = false;
public RenderModelItem(IItemModel mdl, ResourceLocation texture) {
model = mdl;
texturePath = texture;
}
public RenderModelItem setRenderInventory(boolean b) {
renderInventory = b;
return this;
}
public RenderModelItem setRenderEntityItem(boolean b) {
renderEntityItem = b;
return this;
}
public RenderModelItem setInventorySpin(boolean b) {
inventorySpin = b;
return this;
}
public RenderModelItem setStdRotation(float x, float y, float z) {
initVec(stdRotation, x, y, z);
return this;
}
public RenderModelItem setEquipRotation(float x, float y, float z) {
initVec(equipRotation, x, y, z);
return this;
}
public RenderModelItem setInvRotation(float x, float y, float z) {
initVec(invRotation, x, y, z);
return this;
}
public RenderModelItem setEntityItemRotation(float b0, float b1, float b2) {
initVec(entityItemRotation, b0, b1, b2);
return this;
}
public RenderModelItem setScale(double s) {
scale = s;
return this;
}
public RenderModelItem setInvScale(double s) {
invScale = s;
return this;
}
public RenderModelItem setOffset(double offsetX, double offsetY, double offsetZ) {
initVec(stdOffset, offsetX, offsetY, offsetZ);
return this;
}
public RenderModelItem setInvOffset(double offsetX, double offsetY) {
this.invOffset.set(offsetX, offsetY);
return this;
}
public RenderModelItem setEquipOffset(double b0, double b1, double b2) {
initVec(equipOffset, b0, b1, b2);
return this;
}
public RenderModelItem setInformationFrom(RenderModelItem a) {
this.renderInventory = a.renderInventory;
this.invOffset = a.invOffset;
this.setInvScale(a.invScale);
this.stdOffset = a.stdOffset;
this.stdRotation = a.stdRotation;
this.scale = a.scale;
return this;
}
@Override
public boolean handleRenderType(ItemStack item, ItemRenderType type) {
switch (type) {
case EQUIPPED:
case EQUIPPED_FIRST_PERSON:
return true;
case ENTITY:
return renderEntityItem;
case INVENTORY:
return renderInventory;
default:
return false;
}
}
@Override
public boolean shouldUseRenderHelper(ItemRenderType type, ItemStack item,
ItemRendererHelper helper) {
switch (helper) {
case ENTITY_ROTATION:
case ENTITY_BOBBING:
return true;
default:
return false;
}
}
@Override
public void renderItem(ItemRenderType type, ItemStack item, Object... data) {
GL11.glEnable(GL11.GL_BLEND);
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
switch (type) {
case EQUIPPED:
case EQUIPPED_FIRST_PERSON:
renderEquipped(item, (RenderBlocks) data[0], (EntityLivingBase) data[1], type);
break;
case ENTITY:
renderEntityItem((RenderBlocks)data[0], (EntityItem) data[1]);
break;
case INVENTORY:
renderInventory();
break;
default:
break;
}
}
public void renderInventory() {
GL11.glDisable(GL11.GL_CULL_FACE);
GL11.glPushMatrix(); {
RenderUtils.loadTexture(texturePath);
GL11.glTranslated(8.0F + invOffset.x, 8.0F + invOffset.y, 0.0F);
GL11.glScaled(16F * invScale, 16F * invScale, 16F * invScale);
float rotation = 145F;
if(inventorySpin) rotation = GameTimer.getAbsTime() / 100F;
GL11.glRotatef(rotation, 0, 1, 0);
this.doRotation(invRotation);
GL11.glScalef(-1F, -1F, 1F);
renderAtStdPosition();
} GL11.glPopMatrix();
GL11.glEnable(GL11.GL_CULL_FACE);
}
public void renderEntityItem(RenderBlocks render, EntityItem ent) {
GL11.glPushMatrix(); {
RenderUtils.loadTexture(texturePath);
this.doRotation(entityItemRotation);
GL11.glScaled(entityItemScale, entityItemScale, entityItemScale);
renderAtStdPosition();
} GL11.glPopMatrix();
}
public void renderEquipped(ItemStack item, RenderBlocks render,
EntityLivingBase entity, ItemRenderType type) {
if (item.stackTagCompound == null)
item.stackTagCompound = new NBTTagCompound();
GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.glPushMatrix(); {
RenderUtils.loadTexture(texturePath);
float sc2 = 0.0625F;
GL11.glRotatef(40F, 0, 0, 1);
if(type == ItemRenderType.EQUIPPED)
this.doTransformation(thirdPersonOffset);
this.doTransformation(equipOffset);
this.doRotation(equipRotation);
GL11.glRotatef(90, 0, -1, 0);
GL11.glScaled(equipScale, equipScale, equipScale);
if(type == ItemRenderType.EQUIPPED)
GL11.glScaled(thirdPersonScale, thirdPersonScale, thirdPersonScale);
renderAtStdPosition(getModelAttribute(item, entity));
} GL11.glPopMatrix();
}
protected final void renderAtStdPosition() {
renderAtStdPosition(0.0F);
}
protected void renderAtStdPosition(float i) {
GL11.glScaled(scale, scale, scale);
GL11.glDisable(GL11.GL_CULL_FACE);
this.doTransformation(stdOffset);
GL11.glScalef(-1F , -1F , 1F );
GL11.glRotated(stdRotation.yCoord + 180, 0.0F, 1.0F, 0.0F);
GL11.glRotated(stdRotation.zCoord, 0.0F, 0.0F, 1.0F);
GL11.glRotated(stdRotation.xCoord, 1.0F, 0.0F, 0.0F);
model.render(null, 0.0625F, i);
GL11.glEnable(GL11.GL_CULL_FACE);
}
protected float getModelAttribute(ItemStack item, EntityLivingBase entity) {
return 0.1F;
}
protected void doTransformation(Vec3 vec3) {
if(vec3 != null)
GL11.glTranslated(vec3.xCoord, vec3.yCoord, vec3.zCoord);
}
protected void doRotation(Vec3 vec3) {
if(vec3 != null) {
GL11.glRotated(vec3.yCoord, 0.0F, 1.0F, 0.0F);
GL11.glRotated(vec3.zCoord, 0.0F, 0.0F, 1.0F);
GL11.glRotated(vec3.xCoord, 1.0F, 0.0F, 0.0F);
}
}
protected static void initVec(Vec3 vec) {
vec = vec == null ? Vec3.createVectorHelper(0D, 0D, 0D) : vec;
}
protected static void initVec(Vec3 vec, Vec3 another) {
initVec(vec, another.xCoord, another.yCoord, another.zCoord);
}
protected static Vec3 initVec() {
return Vec3.createVectorHelper(0D, 0D, 0D);
}
protected static void initVec(Vec3 vec, double x, double y, double z) {
if(vec == null)
vec = Vec3.createVectorHelper(x, y, z);
else {
vec.xCoord = x;
vec.yCoord = y;
vec.zCoord = z;
}
}
}