    001package net.minecraft.client.renderer;
    002
    003import cpw.mods.fml.relauncher.Side;
    004import cpw.mods.fml.relauncher.SideOnly;
    005import java.nio.FloatBuffer;
    006import java.nio.IntBuffer;
    007import net.minecraft.block.Block;
    008import net.minecraft.block.BlockFluid;
    009import net.minecraft.entity.EntityLiving;
    010import net.minecraft.entity.player.EntityPlayer;
    011import net.minecraft.util.MathHelper;
    012import net.minecraft.util.Vec3;
    013import net.minecraft.world.ChunkPosition;
    014import net.minecraft.world.World;
    015import org.lwjgl.opengl.GL11;
    016import org.lwjgl.util.glu.GLU;
    017
    018@SideOnly(Side.CLIENT)
    019public class ActiveRenderInfo
    020{
    021    /** The calculated view object X coordinate */
    022    public static float objectX = 0.0F;
    023
    024    /** The calculated view object Y coordinate */
    025    public static float objectY = 0.0F;
    026
    027    /** The calculated view object Z coordinate */
    028    public static float objectZ = 0.0F;
    029
    030    /** The current GL viewport */
    031    private static IntBuffer viewport = GLAllocation.createDirectIntBuffer(16);
    032
    033    /** The current GL modelview matrix */
    034    private static FloatBuffer modelview = GLAllocation.createDirectFloatBuffer(16);
    035
    036    /** The current GL projection matrix */
    037    private static FloatBuffer projection = GLAllocation.createDirectFloatBuffer(16);
    038
    039    /** The computed view object coordinates */
    040    private static FloatBuffer objectCoords = GLAllocation.createDirectFloatBuffer(3);
    041
    042    /** The X component of the entity's yaw rotation */
    043    public static float rotationX;
    044
    045    /** The combined X and Z components of the entity's pitch rotation */
    046    public static float rotationXZ;
    047
    048    /** The Z component of the entity's yaw rotation */
    049    public static float rotationZ;
    050
    051    /**
    052     * The Y component (scaled along the Z axis) of the entity's pitch rotation
    053     */
    054    public static float rotationYZ;
    055
    056    /**
    057     * The Y component (scaled along the X axis) of the entity's pitch rotation
    058     */
    059    public static float rotationXY;
    060
    061    /**
    062     * Updates the current render info and camera location based on entity look angles and 1st/3rd person view mode
    063     */
    064    public static void updateRenderInfo(EntityPlayer par0EntityPlayer, boolean par1)
    065    {
    066        GL11.glGetFloat(GL11.GL_MODELVIEW_MATRIX, modelview);
    067        GL11.glGetFloat(GL11.GL_PROJECTION_MATRIX, projection);
    068        GL11.glGetInteger(GL11.GL_VIEWPORT, viewport);
    069        float f = (float)((viewport.get(0) + viewport.get(2)) / 2);
    070        float f1 = (float)((viewport.get(1) + viewport.get(3)) / 2);
    071        GLU.gluUnProject(f, f1, 0.0F, modelview, projection, viewport, objectCoords);
    072        objectX = objectCoords.get(0);
    073        objectY = objectCoords.get(1);
    074        objectZ = objectCoords.get(2);
    075        int i = par1 ? 1 : 0;
    076        float f2 = par0EntityPlayer.rotationPitch;
    077        float f3 = par0EntityPlayer.rotationYaw;
    078        rotationX = MathHelper.cos(f3 * (float)Math.PI / 180.0F) * (float)(1 - i * 2);
    079        rotationZ = MathHelper.sin(f3 * (float)Math.PI / 180.0F) * (float)(1 - i * 2);
    080        rotationYZ = -rotationZ * MathHelper.sin(f2 * (float)Math.PI / 180.0F) * (float)(1 - i * 2);
    081        rotationXY = rotationX * MathHelper.sin(f2 * (float)Math.PI / 180.0F) * (float)(1 - i * 2);
    082        rotationXZ = MathHelper.cos(f2 * (float)Math.PI / 180.0F);
    083    }
    084
    085    /**
    086     * Returns a vector representing the projection along the given entity's view for the given distance
    087     */
    088    public static Vec3 projectViewFromEntity(EntityLiving par0EntityLiving, double par1)
    089    {
    090        double d1 = par0EntityLiving.prevPosX + (par0EntityLiving.posX - par0EntityLiving.prevPosX) * par1;
    091        double d2 = par0EntityLiving.prevPosY + (par0EntityLiving.posY - par0EntityLiving.prevPosY) * par1 + (double)par0EntityLiving.getEyeHeight();
    092        double d3 = par0EntityLiving.prevPosZ + (par0EntityLiving.posZ - par0EntityLiving.prevPosZ) * par1;
    093        double d4 = d1 + (double)(objectX * 1.0F);
    094        double d5 = d2 + (double)(objectY * 1.0F);
    095        double d6 = d3 + (double)(objectZ * 1.0F);
    096        return par0EntityLiving.worldObj.getWorldVec3Pool().getVecFromPool(d4, d5, d6);
    097    }
    098
    099    /**
    100     * Returns the block ID at the current camera location (either air or fluid), taking into account the height of
    101     * fluid blocks
    102     */
    103    public static int getBlockIdAtEntityViewpoint(World par0World, EntityLiving par1EntityLiving, float par2)
    104    {
    105        Vec3 vec3 = projectViewFromEntity(par1EntityLiving, (double)par2);
    106        ChunkPosition chunkposition = new ChunkPosition(vec3);
    107        int i = par0World.getBlockId(chunkposition.x, chunkposition.y, chunkposition.z);
    108
    109        if (i != 0 && Block.blocksList[i].blockMaterial.isLiquid())
    110        {
    111            float f1 = BlockFluid.getFluidHeightPercent(par0World.getBlockMetadata(chunkposition.x, chunkposition.y, chunkposition.z)) - 0.11111111F;
    112            float f2 = (float)(chunkposition.y + 1) - f1;
    113
    114            if (vec3.yCoord >= (double)f2)
    115            {
    116                i = par0World.getBlockId(chunkposition.x, chunkposition.y + 1, chunkposition.z);
    117            }
    118        }
    119
    120        return i;
    121    }
    122}