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 var2 = (float)((viewport.get(0) + viewport.get(2)) / 2);
070        float var3 = (float)((viewport.get(1) + viewport.get(3)) / 2);
071        GLU.gluUnProject(var2, var3, 0.0F, modelview, projection, viewport, objectCoords);
072        objectX = objectCoords.get(0);
073        objectY = objectCoords.get(1);
074        objectZ = objectCoords.get(2);
075        int var4 = par1 ? 1 : 0;
076        float var5 = par0EntityPlayer.rotationPitch;
077        float var6 = par0EntityPlayer.rotationYaw;
078        rotationX = MathHelper.cos(var6 * (float)Math.PI / 180.0F) * (float)(1 - var4 * 2);
079        rotationZ = MathHelper.sin(var6 * (float)Math.PI / 180.0F) * (float)(1 - var4 * 2);
080        rotationYZ = -rotationZ * MathHelper.sin(var5 * (float)Math.PI / 180.0F) * (float)(1 - var4 * 2);
081        rotationXY = rotationX * MathHelper.sin(var5 * (float)Math.PI / 180.0F) * (float)(1 - var4 * 2);
082        rotationXZ = MathHelper.cos(var5 * (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 var3 = par0EntityLiving.prevPosX + (par0EntityLiving.posX - par0EntityLiving.prevPosX) * par1;
091        double var5 = par0EntityLiving.prevPosY + (par0EntityLiving.posY - par0EntityLiving.prevPosY) * par1 + (double)par0EntityLiving.getEyeHeight();
092        double var7 = par0EntityLiving.prevPosZ + (par0EntityLiving.posZ - par0EntityLiving.prevPosZ) * par1;
093        double var9 = var3 + (double)(objectX * 1.0F);
094        double var11 = var5 + (double)(objectY * 1.0F);
095        double var13 = var7 + (double)(objectZ * 1.0F);
096        return par0EntityLiving.worldObj.getWorldVec3Pool().getVecFromPool(var9, var11, var13);
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 var3 = projectViewFromEntity(par1EntityLiving, (double)par2);
106        ChunkPosition var4 = new ChunkPosition(var3);
107        int var5 = par0World.getBlockId(var4.x, var4.y, var4.z);
108
109        if (var5 != 0 && Block.blocksList[var5].blockMaterial.isLiquid())
110        {
111            float var6 = BlockFluid.getFluidHeightPercent(par0World.getBlockMetadata(var4.x, var4.y, var4.z)) - 0.11111111F;
112            float var7 = (float)(var4.y + 1) - var6;
113
114            if (var3.yCoord >= (double)var7)
115            {
116                var5 = par0World.getBlockId(var4.x, var4.y + 1, var4.z);
117            }
118        }
119
120        return var5;
121    }
122}