    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    }