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    }