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