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}