    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    }