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 }