001    package net.minecraft.src;
002    
003    import cpw.mods.fml.common.Side;
004    import cpw.mods.fml.common.asm.SideOnly;
005    
006    public class Vec3
007    {
008        private static final ThreadLocal myVec3LocalPool = new Vec3LocalPool();
009    
010        /** X coordinate of Vec3D */
011        public double xCoord;
012    
013        /** Y coordinate of Vec3D */
014        public double yCoord;
015    
016        /** Z coordinate of Vec3D */
017        public double zCoord;
018    
019        /**
020         * Static method for creating a new Vec3D given the three x,y,z values. This is only called from the other static
021         * method which creates and places it in the list.
022         */
023        public static Vec3 createVectorHelper(double par0, double par2, double par4)
024        {
025            return new Vec3(par0, par2, par4);
026        }
027    
028        public static Vec3Pool getVec3Pool()
029        {
030            return (Vec3Pool)myVec3LocalPool.get();
031        }
032    
033        protected Vec3(double par1, double par3, double par5)
034        {
035            if (par1 == -0.0D)
036            {
037                par1 = 0.0D;
038            }
039    
040            if (par3 == -0.0D)
041            {
042                par3 = 0.0D;
043            }
044    
045            if (par5 == -0.0D)
046            {
047                par5 = 0.0D;
048            }
049    
050            this.xCoord = par1;
051            this.yCoord = par3;
052            this.zCoord = par5;
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        /**
067         * Normalizes the vector to a length of 1 (except if it is the zero vector)
068         */
069        public Vec3 normalize()
070        {
071            double var1 = (double)MathHelper.sqrt_double(this.xCoord * this.xCoord + this.yCoord * this.yCoord + this.zCoord * this.zCoord);
072            return var1 < 1.0E-4D ? getVec3Pool().getVecFromPool(0.0D, 0.0D, 0.0D) : getVec3Pool().getVecFromPool(this.xCoord / var1, this.yCoord / var1, this.zCoord / var1);
073        }
074    
075        public double dotProduct(Vec3 par1Vec3)
076        {
077            return this.xCoord * par1Vec3.xCoord + this.yCoord * par1Vec3.yCoord + this.zCoord * par1Vec3.zCoord;
078        }
079    
080        @SideOnly(Side.CLIENT)
081    
082        /**
083         * Returns a new vector with the result of the specified vector minus this.
084         */
085        public Vec3 subtract(Vec3 par1Vec3)
086        {
087            return getVec3Pool().getVecFromPool(par1Vec3.xCoord - this.xCoord, par1Vec3.yCoord - this.yCoord, par1Vec3.zCoord - this.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 getVec3Pool().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 getVec3Pool().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 var2 = par1Vec3.xCoord - this.xCoord;
115            double var4 = par1Vec3.yCoord - this.yCoord;
116            double var6 = par1Vec3.zCoord - this.zCoord;
117            return (double)MathHelper.sqrt_double(var2 * var2 + var4 * var4 + var6 * var6);
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 var2 = par1Vec3.xCoord - this.xCoord;
126            double var4 = par1Vec3.yCoord - this.yCoord;
127            double var6 = par1Vec3.zCoord - this.zCoord;
128            return var2 * var2 + var4 * var4 + var6 * var6;
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 var7 = par1 - this.xCoord;
137            double var9 = par3 - this.yCoord;
138            double var11 = par5 - this.zCoord;
139            return var7 * var7 + var9 * var9 + var11 * var11;
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 var4 = par1Vec3.xCoord - this.xCoord;
157            double var6 = par1Vec3.yCoord - this.yCoord;
158            double var8 = par1Vec3.zCoord - this.zCoord;
159    
160            if (var4 * var4 < 1.0000000116860974E-7D)
161            {
162                return null;
163            }
164            else
165            {
166                double var10 = (par2 - this.xCoord) / var4;
167                return var10 >= 0.0D && var10 <= 1.0D ? getVec3Pool().getVecFromPool(this.xCoord + var4 * var10, this.yCoord + var6 * var10, this.zCoord + var8 * var10) : 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 var4 = par1Vec3.xCoord - this.xCoord;
178            double var6 = par1Vec3.yCoord - this.yCoord;
179            double var8 = par1Vec3.zCoord - this.zCoord;
180    
181            if (var6 * var6 < 1.0000000116860974E-7D)
182            {
183                return null;
184            }
185            else
186            {
187                double var10 = (par2 - this.yCoord) / var6;
188                return var10 >= 0.0D && var10 <= 1.0D ? getVec3Pool().getVecFromPool(this.xCoord + var4 * var10, this.yCoord + var6 * var10, this.zCoord + var8 * var10) : 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 var4 = par1Vec3.xCoord - this.xCoord;
199            double var6 = par1Vec3.yCoord - this.yCoord;
200            double var8 = par1Vec3.zCoord - this.zCoord;
201    
202            if (var8 * var8 < 1.0000000116860974E-7D)
203            {
204                return null;
205            }
206            else
207            {
208                double var10 = (par2 - this.zCoord) / var8;
209                return var10 >= 0.0D && var10 <= 1.0D ? getVec3Pool().getVecFromPool(this.xCoord + var4 * var10, this.yCoord + var6 * var10, this.zCoord + var8 * var10) : 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 var2 = MathHelper.cos(par1);
224            float var3 = MathHelper.sin(par1);
225            double var4 = this.xCoord;
226            double var6 = this.yCoord * (double)var2 + this.zCoord * (double)var3;
227            double var8 = this.zCoord * (double)var2 - this.yCoord * (double)var3;
228            this.xCoord = var4;
229            this.yCoord = var6;
230            this.zCoord = var8;
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 var2 = MathHelper.cos(par1);
239            float var3 = MathHelper.sin(par1);
240            double var4 = this.xCoord * (double)var2 + this.zCoord * (double)var3;
241            double var6 = this.yCoord;
242            double var8 = this.zCoord * (double)var2 - this.xCoord * (double)var3;
243            this.xCoord = var4;
244            this.yCoord = var6;
245            this.zCoord = var8;
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 var2 = MathHelper.cos(par1);
256            float var3 = MathHelper.sin(par1);
257            double var4 = this.xCoord * (double)var2 + this.yCoord * (double)var3;
258            double var6 = this.yCoord * (double)var2 - this.xCoord * (double)var3;
259            double var8 = this.zCoord;
260            this.xCoord = var4;
261            this.yCoord = var6;
262            this.zCoord = var8;
263        }
264    }