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 AxisAlignedBB 007 { 008 /** ThreadLocal AABBPool */ 009 private static final ThreadLocal theAABBLocalPool = new AABBLocalPool(); 010 public double minX; 011 public double minY; 012 public double minZ; 013 public double maxX; 014 public double maxY; 015 public double maxZ; 016 017 /** 018 * Returns a bounding box with the specified bounds. Args: minX, minY, minZ, maxX, maxY, maxZ 019 */ 020 public static AxisAlignedBB getBoundingBox(double par0, double par2, double par4, double par6, double par8, double par10) 021 { 022 return new AxisAlignedBB(par0, par2, par4, par6, par8, par10); 023 } 024 025 /** 026 * Gets the ThreadLocal AABBPool 027 */ 028 public static AABBPool getAABBPool() 029 { 030 return (AABBPool)theAABBLocalPool.get(); 031 } 032 033 protected AxisAlignedBB(double par1, double par3, double par5, double par7, double par9, double par11) 034 { 035 this.minX = par1; 036 this.minY = par3; 037 this.minZ = par5; 038 this.maxX = par7; 039 this.maxY = par9; 040 this.maxZ = par11; 041 } 042 043 /** 044 * Sets the bounds of the bounding box. Args: minX, minY, minZ, maxX, maxY, maxZ 045 */ 046 public AxisAlignedBB setBounds(double par1, double par3, double par5, double par7, double par9, double par11) 047 { 048 this.minX = par1; 049 this.minY = par3; 050 this.minZ = par5; 051 this.maxX = par7; 052 this.maxY = par9; 053 this.maxZ = par11; 054 return this; 055 } 056 057 /** 058 * Adds the coordinates to the bounding box extending it if the point lies outside the current ranges. Args: x, y, z 059 */ 060 public AxisAlignedBB addCoord(double par1, double par3, double par5) 061 { 062 double var7 = this.minX; 063 double var9 = this.minY; 064 double var11 = this.minZ; 065 double var13 = this.maxX; 066 double var15 = this.maxY; 067 double var17 = this.maxZ; 068 069 if (par1 < 0.0D) 070 { 071 var7 += par1; 072 } 073 074 if (par1 > 0.0D) 075 { 076 var13 += par1; 077 } 078 079 if (par3 < 0.0D) 080 { 081 var9 += par3; 082 } 083 084 if (par3 > 0.0D) 085 { 086 var15 += par3; 087 } 088 089 if (par5 < 0.0D) 090 { 091 var11 += par5; 092 } 093 094 if (par5 > 0.0D) 095 { 096 var17 += par5; 097 } 098 099 return getAABBPool().addOrModifyAABBInPool(var7, var9, var11, var13, var15, var17); 100 } 101 102 /** 103 * Returns a bounding box expanded by the specified vector (if negative numbers are given it will shrink). Args: x, 104 * y, z 105 */ 106 public AxisAlignedBB expand(double par1, double par3, double par5) 107 { 108 double var7 = this.minX - par1; 109 double var9 = this.minY - par3; 110 double var11 = this.minZ - par5; 111 double var13 = this.maxX + par1; 112 double var15 = this.maxY + par3; 113 double var17 = this.maxZ + par5; 114 return getAABBPool().addOrModifyAABBInPool(var7, var9, var11, var13, var15, var17); 115 } 116 117 /** 118 * Returns a bounding box offseted by the specified vector (if negative numbers are given it will shrink). Args: x, 119 * y, z 120 */ 121 public AxisAlignedBB getOffsetBoundingBox(double par1, double par3, double par5) 122 { 123 return getAABBPool().addOrModifyAABBInPool(this.minX + par1, this.minY + par3, this.minZ + par5, this.maxX + par1, this.maxY + par3, this.maxZ + par5); 124 } 125 126 /** 127 * if instance and the argument bounding boxes overlap in the Y and Z dimensions, calculate the offset between them 128 * in the X dimension. return var2 if the bounding boxes do not overlap or if var2 is closer to 0 then the 129 * calculated offset. Otherwise return the calculated offset. 130 */ 131 public double calculateXOffset(AxisAlignedBB par1AxisAlignedBB, double par2) 132 { 133 if (par1AxisAlignedBB.maxY > this.minY && par1AxisAlignedBB.minY < this.maxY) 134 { 135 if (par1AxisAlignedBB.maxZ > this.minZ && par1AxisAlignedBB.minZ < this.maxZ) 136 { 137 double var4; 138 139 if (par2 > 0.0D && par1AxisAlignedBB.maxX <= this.minX) 140 { 141 var4 = this.minX - par1AxisAlignedBB.maxX; 142 143 if (var4 < par2) 144 { 145 par2 = var4; 146 } 147 } 148 149 if (par2 < 0.0D && par1AxisAlignedBB.minX >= this.maxX) 150 { 151 var4 = this.maxX - par1AxisAlignedBB.minX; 152 153 if (var4 > par2) 154 { 155 par2 = var4; 156 } 157 } 158 159 return par2; 160 } 161 else 162 { 163 return par2; 164 } 165 } 166 else 167 { 168 return par2; 169 } 170 } 171 172 /** 173 * if instance and the argument bounding boxes overlap in the X and Z dimensions, calculate the offset between them 174 * in the Y dimension. return var2 if the bounding boxes do not overlap or if var2 is closer to 0 then the 175 * calculated offset. Otherwise return the calculated offset. 176 */ 177 public double calculateYOffset(AxisAlignedBB par1AxisAlignedBB, double par2) 178 { 179 if (par1AxisAlignedBB.maxX > this.minX && par1AxisAlignedBB.minX < this.maxX) 180 { 181 if (par1AxisAlignedBB.maxZ > this.minZ && par1AxisAlignedBB.minZ < this.maxZ) 182 { 183 double var4; 184 185 if (par2 > 0.0D && par1AxisAlignedBB.maxY <= this.minY) 186 { 187 var4 = this.minY - par1AxisAlignedBB.maxY; 188 189 if (var4 < par2) 190 { 191 par2 = var4; 192 } 193 } 194 195 if (par2 < 0.0D && par1AxisAlignedBB.minY >= this.maxY) 196 { 197 var4 = this.maxY - par1AxisAlignedBB.minY; 198 199 if (var4 > par2) 200 { 201 par2 = var4; 202 } 203 } 204 205 return par2; 206 } 207 else 208 { 209 return par2; 210 } 211 } 212 else 213 { 214 return par2; 215 } 216 } 217 218 /** 219 * if instance and the argument bounding boxes overlap in the Y and X dimensions, calculate the offset between them 220 * in the Z dimension. return var2 if the bounding boxes do not overlap or if var2 is closer to 0 then the 221 * calculated offset. Otherwise return the calculated offset. 222 */ 223 public double calculateZOffset(AxisAlignedBB par1AxisAlignedBB, double par2) 224 { 225 if (par1AxisAlignedBB.maxX > this.minX && par1AxisAlignedBB.minX < this.maxX) 226 { 227 if (par1AxisAlignedBB.maxY > this.minY && par1AxisAlignedBB.minY < this.maxY) 228 { 229 double var4; 230 231 if (par2 > 0.0D && par1AxisAlignedBB.maxZ <= this.minZ) 232 { 233 var4 = this.minZ - par1AxisAlignedBB.maxZ; 234 235 if (var4 < par2) 236 { 237 par2 = var4; 238 } 239 } 240 241 if (par2 < 0.0D && par1AxisAlignedBB.minZ >= this.maxZ) 242 { 243 var4 = this.maxZ - par1AxisAlignedBB.minZ; 244 245 if (var4 > par2) 246 { 247 par2 = var4; 248 } 249 } 250 251 return par2; 252 } 253 else 254 { 255 return par2; 256 } 257 } 258 else 259 { 260 return par2; 261 } 262 } 263 264 /** 265 * Returns whether the given bounding box intersects with this one. Args: axisAlignedBB 266 */ 267 public boolean intersectsWith(AxisAlignedBB par1AxisAlignedBB) 268 { 269 return par1AxisAlignedBB.maxX > this.minX && par1AxisAlignedBB.minX < this.maxX ? (par1AxisAlignedBB.maxY > this.minY && par1AxisAlignedBB.minY < this.maxY ? par1AxisAlignedBB.maxZ > this.minZ && par1AxisAlignedBB.minZ < this.maxZ : false) : false; 270 } 271 272 /** 273 * Offsets the current bounding box by the specified coordinates. Args: x, y, z 274 */ 275 public AxisAlignedBB offset(double par1, double par3, double par5) 276 { 277 this.minX += par1; 278 this.minY += par3; 279 this.minZ += par5; 280 this.maxX += par1; 281 this.maxY += par3; 282 this.maxZ += par5; 283 return this; 284 } 285 286 /** 287 * Returns if the supplied Vec3D is completely inside the bounding box 288 */ 289 public boolean isVecInside(Vec3 par1Vec3) 290 { 291 return par1Vec3.xCoord > this.minX && par1Vec3.xCoord < this.maxX ? (par1Vec3.yCoord > this.minY && par1Vec3.yCoord < this.maxY ? par1Vec3.zCoord > this.minZ && par1Vec3.zCoord < this.maxZ : false) : false; 292 } 293 294 @SideOnly(Side.CLIENT) 295 296 /** 297 * Returns the average length of the edges of the bounding box. 298 */ 299 public double getAverageEdgeLength() 300 { 301 double var1 = this.maxX - this.minX; 302 double var3 = this.maxY - this.minY; 303 double var5 = this.maxZ - this.minZ; 304 return (var1 + var3 + var5) / 3.0D; 305 } 306 307 /** 308 * Returns a bounding box that is inset by the specified amounts 309 */ 310 public AxisAlignedBB contract(double par1, double par3, double par5) 311 { 312 double var7 = this.minX + par1; 313 double var9 = this.minY + par3; 314 double var11 = this.minZ + par5; 315 double var13 = this.maxX - par1; 316 double var15 = this.maxY - par3; 317 double var17 = this.maxZ - par5; 318 return getAABBPool().addOrModifyAABBInPool(var7, var9, var11, var13, var15, var17); 319 } 320 321 /** 322 * Returns a copy of the bounding box. 323 */ 324 public AxisAlignedBB copy() 325 { 326 return getAABBPool().addOrModifyAABBInPool(this.minX, this.minY, this.minZ, this.maxX, this.maxY, this.maxZ); 327 } 328 329 public MovingObjectPosition calculateIntercept(Vec3 par1Vec3, Vec3 par2Vec3) 330 { 331 Vec3 var3 = par1Vec3.getIntermediateWithXValue(par2Vec3, this.minX); 332 Vec3 var4 = par1Vec3.getIntermediateWithXValue(par2Vec3, this.maxX); 333 Vec3 var5 = par1Vec3.getIntermediateWithYValue(par2Vec3, this.minY); 334 Vec3 var6 = par1Vec3.getIntermediateWithYValue(par2Vec3, this.maxY); 335 Vec3 var7 = par1Vec3.getIntermediateWithZValue(par2Vec3, this.minZ); 336 Vec3 var8 = par1Vec3.getIntermediateWithZValue(par2Vec3, this.maxZ); 337 338 if (!this.isVecInYZ(var3)) 339 { 340 var3 = null; 341 } 342 343 if (!this.isVecInYZ(var4)) 344 { 345 var4 = null; 346 } 347 348 if (!this.isVecInXZ(var5)) 349 { 350 var5 = null; 351 } 352 353 if (!this.isVecInXZ(var6)) 354 { 355 var6 = null; 356 } 357 358 if (!this.isVecInXY(var7)) 359 { 360 var7 = null; 361 } 362 363 if (!this.isVecInXY(var8)) 364 { 365 var8 = null; 366 } 367 368 Vec3 var9 = null; 369 370 if (var3 != null && (var9 == null || par1Vec3.squareDistanceTo(var3) < par1Vec3.squareDistanceTo(var9))) 371 { 372 var9 = var3; 373 } 374 375 if (var4 != null && (var9 == null || par1Vec3.squareDistanceTo(var4) < par1Vec3.squareDistanceTo(var9))) 376 { 377 var9 = var4; 378 } 379 380 if (var5 != null && (var9 == null || par1Vec3.squareDistanceTo(var5) < par1Vec3.squareDistanceTo(var9))) 381 { 382 var9 = var5; 383 } 384 385 if (var6 != null && (var9 == null || par1Vec3.squareDistanceTo(var6) < par1Vec3.squareDistanceTo(var9))) 386 { 387 var9 = var6; 388 } 389 390 if (var7 != null && (var9 == null || par1Vec3.squareDistanceTo(var7) < par1Vec3.squareDistanceTo(var9))) 391 { 392 var9 = var7; 393 } 394 395 if (var8 != null && (var9 == null || par1Vec3.squareDistanceTo(var8) < par1Vec3.squareDistanceTo(var9))) 396 { 397 var9 = var8; 398 } 399 400 if (var9 == null) 401 { 402 return null; 403 } 404 else 405 { 406 byte var10 = -1; 407 408 if (var9 == var3) 409 { 410 var10 = 4; 411 } 412 413 if (var9 == var4) 414 { 415 var10 = 5; 416 } 417 418 if (var9 == var5) 419 { 420 var10 = 0; 421 } 422 423 if (var9 == var6) 424 { 425 var10 = 1; 426 } 427 428 if (var9 == var7) 429 { 430 var10 = 2; 431 } 432 433 if (var9 == var8) 434 { 435 var10 = 3; 436 } 437 438 return new MovingObjectPosition(0, 0, 0, var10, var9); 439 } 440 } 441 442 /** 443 * Checks if the specified vector is within the YZ dimensions of the bounding box. Args: Vec3D 444 */ 445 private boolean isVecInYZ(Vec3 par1Vec3) 446 { 447 return par1Vec3 == null ? false : par1Vec3.yCoord >= this.minY && par1Vec3.yCoord <= this.maxY && par1Vec3.zCoord >= this.minZ && par1Vec3.zCoord <= this.maxZ; 448 } 449 450 /** 451 * Checks if the specified vector is within the XZ dimensions of the bounding box. Args: Vec3D 452 */ 453 private boolean isVecInXZ(Vec3 par1Vec3) 454 { 455 return par1Vec3 == null ? false : par1Vec3.xCoord >= this.minX && par1Vec3.xCoord <= this.maxX && par1Vec3.zCoord >= this.minZ && par1Vec3.zCoord <= this.maxZ; 456 } 457 458 /** 459 * Checks if the specified vector is within the XY dimensions of the bounding box. Args: Vec3D 460 */ 461 private boolean isVecInXY(Vec3 par1Vec3) 462 { 463 return par1Vec3 == null ? false : par1Vec3.xCoord >= this.minX && par1Vec3.xCoord <= this.maxX && par1Vec3.yCoord >= this.minY && par1Vec3.yCoord <= this.maxY; 464 } 465 466 /** 467 * Sets the bounding box to the same bounds as the bounding box passed in. Args: axisAlignedBB 468 */ 469 public void setBB(AxisAlignedBB par1AxisAlignedBB) 470 { 471 this.minX = par1AxisAlignedBB.minX; 472 this.minY = par1AxisAlignedBB.minY; 473 this.minZ = par1AxisAlignedBB.minZ; 474 this.maxX = par1AxisAlignedBB.maxX; 475 this.maxY = par1AxisAlignedBB.maxY; 476 this.maxZ = par1AxisAlignedBB.maxZ; 477 } 478 479 public String toString() 480 { 481 return "box[" + this.minX + ", " + this.minY + ", " + this.minZ + " -> " + this.maxX + ", " + this.maxY + ", " + this.maxZ + "]"; 482 } 483 }