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