    001package net.minecraft.util;
    002
    003import cpw.mods.fml.relauncher.Side;
    004import cpw.mods.fml.relauncher.SideOnly;
    005
    006public class Vec3
    007{
    008    /**
    009     * A global Vec3Pool that always creates new vectors instead of reusing them and is thread-safe.
    010     */
    011    public static final Vec3Pool fakePool = new Vec3Pool(-1, -1);
    012    public final Vec3Pool myVec3LocalPool;
    013
    014    /** X coordinate of Vec3D */
    015    public double xCoord;
    016
    017    /** Y coordinate of Vec3D */
    018    public double yCoord;
    019
    020    /** Z coordinate of Vec3D */
    021    public double zCoord;
    022
    023    /**
    024     * Static method for creating a new Vec3D given the three x,y,z values. This is only called from the other static
    025     * method which creates and places it in the list.
    026     */
    027    public static Vec3 createVectorHelper(double par0, double par2, double par4)
    028    {
    029        return new Vec3(fakePool, par0, par2, par4);
    030    }
    031
    032    protected Vec3(Vec3Pool par1Vec3Pool, double par2, double par4, double par6)
    033    {
    034        if (par2 == -0.0D)
    035        {
    036            par2 = 0.0D;
    037        }
    038
    039        if (par4 == -0.0D)
    040        {
    041            par4 = 0.0D;
    042        }
    043
    044        if (par6 == -0.0D)
    045        {
    046            par6 = 0.0D;
    047        }
    048
    049        this.xCoord = par2;
    050        this.yCoord = par4;
    051        this.zCoord = par6;
    052        this.myVec3LocalPool = par1Vec3Pool;
    053    }
    054
    055    /**
    056     * Sets the x,y,z components of the vector as specified.
    057     */
    058    protected Vec3 setComponents(double par1, double par3, double par5)
    059    {
    060        this.xCoord = par1;
    061        this.yCoord = par3;
    062        this.zCoord = par5;
    063        return this;
    064    }
    065
    066    @SideOnly(Side.CLIENT)
    067
    068    /**
    069     * Returns a new vector with the result of the specified vector minus this.
    070     */
    071    public Vec3 subtract(Vec3 par1Vec3)
    072    {
    073        return this.myVec3LocalPool.getVecFromPool(par1Vec3.xCoord - this.xCoord, par1Vec3.yCoord - this.yCoord, par1Vec3.zCoord - this.zCoord);
    074    }
    075
    076    /**
    077     * Normalizes the vector to a length of 1 (except if it is the zero vector)
    078     */
    079    public Vec3 normalize()
    080    {
    081        double d0 = (double)MathHelper.sqrt_double(this.xCoord * this.xCoord + this.yCoord * this.yCoord + this.zCoord * this.zCoord);
    082        return d0 < 1.0E-4D ? this.myVec3LocalPool.getVecFromPool(0.0D, 0.0D, 0.0D) : this.myVec3LocalPool.getVecFromPool(this.xCoord / d0, this.yCoord / d0, this.zCoord / d0);
    083    }
    084
    085    public double dotProduct(Vec3 par1Vec3)
    086    {
    087        return this.xCoord * par1Vec3.xCoord + this.yCoord * par1Vec3.yCoord + this.zCoord * par1Vec3.zCoord;
    088    }
    089
    090    @SideOnly(Side.CLIENT)
    091
    092    /**
    093     * Returns a new vector with the result of this vector x the specified vector.
    094     */
    095    public Vec3 crossProduct(Vec3 par1Vec3)
    096    {
    097        return this.myVec3LocalPool.getVecFromPool(this.yCoord * par1Vec3.zCoord - this.zCoord * par1Vec3.yCoord, this.zCoord * par1Vec3.xCoord - this.xCoord * par1Vec3.zCoord, this.xCoord * par1Vec3.yCoord - this.yCoord * par1Vec3.xCoord);
    098    }
    099
    100    /**
    101     * Adds the specified x,y,z vector components to this vector and returns the resulting vector. Does not change this
    102     * vector.
    103     */
    104    public Vec3 addVector(double par1, double par3, double par5)
    105    {
    106        return this.myVec3LocalPool.getVecFromPool(this.xCoord + par1, this.yCoord + par3, this.zCoord + par5);
    107    }
    108
    109    /**
    110     * Euclidean distance between this and the specified vector, returned as double.
    111     */
    112    public double distanceTo(Vec3 par1Vec3)
    113    {
    114        double d0 = par1Vec3.xCoord - this.xCoord;
    115        double d1 = par1Vec3.yCoord - this.yCoord;
    116        double d2 = par1Vec3.zCoord - this.zCoord;
    117        return (double)MathHelper.sqrt_double(d0 * d0 + d1 * d1 + d2 * d2);
    118    }
    119
    120    /**
    121     * The square of the Euclidean distance between this and the specified vector.
    122     */
    123    public double squareDistanceTo(Vec3 par1Vec3)
    124    {
    125        double d0 = par1Vec3.xCoord - this.xCoord;
    126        double d1 = par1Vec3.yCoord - this.yCoord;
    127        double d2 = par1Vec3.zCoord - this.zCoord;
    128        return d0 * d0 + d1 * d1 + d2 * d2;
    129    }
    130
    131    /**
    132     * The square of the Euclidean distance between this and the vector of x,y,z components passed in.
    133     */
    134    public double squareDistanceTo(double par1, double par3, double par5)
    135    {
    136        double d3 = par1 - this.xCoord;
    137        double d4 = par3 - this.yCoord;
    138        double d5 = par5 - this.zCoord;
    139        return d3 * d3 + d4 * d4 + d5 * d5;
    140    }
    141
    142    /**
    143     * Returns the length of the vector.
    144     */
    145    public double lengthVector()
    146    {
    147        return (double)MathHelper.sqrt_double(this.xCoord * this.xCoord + this.yCoord * this.yCoord + this.zCoord * this.zCoord);
    148    }
    149
    150    /**
    151     * Returns a new vector with x value equal to the second parameter, along the line between this vector and the
    152     * passed in vector, or null if not possible.
    153     */
    154    public Vec3 getIntermediateWithXValue(Vec3 par1Vec3, double par2)
    155    {
    156        double d1 = par1Vec3.xCoord - this.xCoord;
    157        double d2 = par1Vec3.yCoord - this.yCoord;
    158        double d3 = par1Vec3.zCoord - this.zCoord;
    159
    160        if (d1 * d1 < 1.0000000116860974E-7D)
    161        {
    162            return null;
    163        }
    164        else
    165        {
    166            double d4 = (par2 - this.xCoord) / d1;
    167            return d4 >= 0.0D && d4 <= 1.0D ? this.myVec3LocalPool.getVecFromPool(this.xCoord + d1 * d4, this.yCoord + d2 * d4, this.zCoord + d3 * d4) : null;
    168        }
    169    }
    170
    171    /**
    172     * Returns a new vector with y value equal to the second parameter, along the line between this vector and the
    173     * passed in vector, or null if not possible.
    174     */
    175    public Vec3 getIntermediateWithYValue(Vec3 par1Vec3, double par2)
    176    {
    177        double d1 = par1Vec3.xCoord - this.xCoord;
    178        double d2 = par1Vec3.yCoord - this.yCoord;
    179        double d3 = par1Vec3.zCoord - this.zCoord;
    180
    181        if (d2 * d2 < 1.0000000116860974E-7D)
    182        {
    183            return null;
    184        }
    185        else
    186        {
    187            double d4 = (par2 - this.yCoord) / d2;
    188            return d4 >= 0.0D && d4 <= 1.0D ? this.myVec3LocalPool.getVecFromPool(this.xCoord + d1 * d4, this.yCoord + d2 * d4, this.zCoord + d3 * d4) : null;
    189        }
    190    }
    191
    192    /**
    193     * Returns a new vector with z value equal to the second parameter, along the line between this vector and the
    194     * passed in vector, or null if not possible.
    195     */
    196    public Vec3 getIntermediateWithZValue(Vec3 par1Vec3, double par2)
    197    {
    198        double d1 = par1Vec3.xCoord - this.xCoord;
    199        double d2 = par1Vec3.yCoord - this.yCoord;
    200        double d3 = par1Vec3.zCoord - this.zCoord;
    201
    202        if (d3 * d3 < 1.0000000116860974E-7D)
    203        {
    204            return null;
    205        }
    206        else
    207        {
    208            double d4 = (par2 - this.zCoord) / d3;
    209            return d4 >= 0.0D && d4 <= 1.0D ? this.myVec3LocalPool.getVecFromPool(this.xCoord + d1 * d4, this.yCoord + d2 * d4, this.zCoord + d3 * d4) : null;
    210        }
    211    }
    212
    213    public String toString()
    214    {
    215        return "(" + this.xCoord + ", " + this.yCoord + ", " + this.zCoord + ")";
    216    }
    217
    218    /**
    219     * Rotates the vector around the x axis by the specified angle.
    220     */
    221    public void rotateAroundX(float par1)
    222    {
    223        float f1 = MathHelper.cos(par1);
    224        float f2 = MathHelper.sin(par1);
    225        double d0 = this.xCoord;
    226        double d1 = this.yCoord * (double)f1 + this.zCoord * (double)f2;
    227        double d2 = this.zCoord * (double)f1 - this.yCoord * (double)f2;
    228        this.xCoord = d0;
    229        this.yCoord = d1;
    230        this.zCoord = d2;
    231    }
    232
    233    /**
    234     * Rotates the vector around the y axis by the specified angle.
    235     */
    236    public void rotateAroundY(float par1)
    237    {
    238        float f1 = MathHelper.cos(par1);
    239        float f2 = MathHelper.sin(par1);
    240        double d0 = this.xCoord * (double)f1 + this.zCoord * (double)f2;
    241        double d1 = this.yCoord;
    242        double d2 = this.zCoord * (double)f1 - this.xCoord * (double)f2;
    243        this.xCoord = d0;
    244        this.yCoord = d1;
    245        this.zCoord = d2;
    246    }
    247
    248    @SideOnly(Side.CLIENT)
    249
    250    /**
    251     * Rotates the vector around the z axis by the specified angle.
    252     */
    253    public void rotateAroundZ(float par1)
    254    {
    255        float f1 = MathHelper.cos(par1);
    256        float f2 = MathHelper.sin(par1);
    257        double d0 = this.xCoord * (double)f1 + this.yCoord * (double)f2;
    258        double d1 = this.yCoord * (double)f1 - this.xCoord * (double)f2;
    259        double d2 = this.zCoord;
    260        this.xCoord = d0;
    261        this.yCoord = d1;
    262        this.zCoord = d2;
    263    }
    264}