/// <summary> /// Checks for an intersection between a ray and an AxisAlignedBoundingBox. /// Uses the algorithm "Fast Ray/Axis-Aligned Bounding Box Overlap Tests using Ray Slopes". /// </summary> /// <param name="b">BoundingBox to check</param> /// <returns>True if an intersection exists</returns> public bool Intersects(AxisAlignedBoundingBox b) { if (dirty) { PreCalculate(); } switch (classification) { case RayType.MMM: if ((origin.X < b.Min.X) || (origin.Y < b.Min.Y) || (origin.Z < b.Min.Z) || (jbyi * b.Min.X - b.Max.Y + c_xy > 0) || (ibyj * b.Min.Y - b.Max.X + c_yx > 0) || (jbyk * b.Min.Z - b.Max.Y + c_zy > 0) || (kbyj * b.Min.Y - b.Max.Z + c_yz > 0) || (kbyi * b.Min.X - b.Max.Z + c_xz > 0) || (ibyk * b.Min.Z - b.Max.X + c_zx > 0)) { return(false); } return(true); case RayType.MMP: if ((origin.X < b.Min.X) || (origin.Y < b.Min.Y) || (origin.Z > b.Max.Z) || (jbyi * b.Min.X - b.Max.Y + c_xy > 0) || (ibyj * b.Min.Y - b.Max.X + c_yx > 0) || (jbyk * b.Max.Z - b.Max.Y + c_zy > 0) || (kbyj * b.Min.Y - b.Min.Z + c_yz < 0) || (kbyi * b.Min.X - b.Min.Z + c_xz < 0) || (ibyk * b.Max.Z - b.Max.X + c_zx > 0)) { return(false); } return(true); case RayType.MPM: if ((origin.X < b.Min.X) || (origin.Y > b.Max.Y) || (origin.Z < b.Min.Z) || (jbyi * b.Min.X - b.Min.Y + c_xy < 0) || (ibyj * b.Max.Y - b.Max.X + c_yx > 0) || (jbyk * b.Min.Z - b.Min.Y + c_zy < 0) || (kbyj * b.Max.Y - b.Max.Z + c_yz > 0) || (kbyi * b.Min.X - b.Max.Z + c_xz > 0) || (ibyk * b.Min.Z - b.Max.X + c_zx > 0)) { return(false); } return(true); case RayType.MPP: if ((origin.X < b.Min.X) || (origin.Y > b.Max.Y) || (origin.Z > b.Max.Z) || (jbyi * b.Min.X - b.Min.Y + c_xy < 0) || (ibyj * b.Max.Y - b.Max.X + c_yx > 0) || (jbyk * b.Max.Z - b.Min.Y + c_zy < 0) || (kbyj * b.Max.Y - b.Min.Z + c_yz < 0) || (kbyi * b.Min.X - b.Min.Z + c_xz < 0) || (ibyk * b.Max.Z - b.Max.X + c_zx > 0)) { return(false); } return(true); case RayType.PMM: if ((origin.X > b.Max.X) || (origin.Y < b.Min.Y) || (origin.Z < b.Min.Z) || (jbyi * b.Max.X - b.Max.Y + c_xy > 0) || (ibyj * b.Min.Y - b.Min.X + c_yx < 0) || (jbyk * b.Min.Z - b.Max.Y + c_zy > 0) || (kbyj * b.Min.Y - b.Max.Z + c_yz > 0) || (kbyi * b.Max.X - b.Max.Z + c_xz > 0) || (ibyk * b.Min.Z - b.Min.X + c_zx < 0)) { return(false); } return(true); case RayType.PMP: if ((origin.X > b.Max.X) || (origin.Y < b.Min.Y) || (origin.Z > b.Max.Z) || (jbyi * b.Max.X - b.Max.Y + c_xy > 0) || (ibyj * b.Min.Y - b.Min.X + c_yx < 0) || (jbyk * b.Max.Z - b.Max.Y + c_zy > 0) || (kbyj * b.Min.Y - b.Min.Z + c_yz < 0) || (kbyi * b.Max.X - b.Min.Z + c_xz < 0) || (ibyk * b.Max.Z - b.Min.X + c_zx < 0)) { return(false); } return(true); case RayType.PPM: if ((origin.X > b.Max.X) || (origin.Y > b.Max.Y) || (origin.Z < b.Min.Z) || (jbyi * b.Max.X - b.Min.Y + c_xy < 0) || (ibyj * b.Max.Y - b.Min.X + c_yx < 0) || (jbyk * b.Min.Z - b.Min.Y + c_zy < 0) || (kbyj * b.Max.Y - b.Max.Z + c_yz > 0) || (kbyi * b.Max.X - b.Max.Z + c_xz > 0) || (ibyk * b.Min.Z - b.Min.X + c_zx < 0)) { return(false); } return(true); case RayType.PPP: if ((origin.X > b.Max.X) || (origin.Y > b.Max.Y) || (origin.Z > b.Max.Z) || (jbyi * b.Max.X - b.Min.Y + c_xy < 0) || (ibyj * b.Max.Y - b.Min.X + c_yx < 0) || (jbyk * b.Max.Z - b.Min.Y + c_zy < 0) || (kbyj * b.Max.Y - b.Min.Z + c_yz < 0) || (kbyi * b.Max.X - b.Min.Z + c_xz < 0) || (ibyk * b.Max.Z - b.Min.X + c_zx < 0)) { return(false); } return(true); case RayType.OMM: if ((origin.X < b.Min.X) || (origin.X > b.Max.X) || (origin.Y < b.Min.Y) || (origin.Z < b.Min.Z) || (jbyk * b.Min.Z - b.Max.Y + c_zy > 0) || (kbyj * b.Min.Y - b.Max.Z + c_yz > 0)) { return(false); } return(true); case RayType.OMP: if ((origin.X < b.Min.X) || (origin.X > b.Max.X) || (origin.Y < b.Min.Y) || (origin.Z > b.Max.Z) || (jbyk * b.Max.Z - b.Max.Y + c_zy > 0) || (kbyj * b.Min.Y - b.Min.Z + c_yz < 0)) { return(false); } return(true); case RayType.OPM: if ((origin.X < b.Min.X) || (origin.X > b.Max.X) || (origin.Y > b.Max.Y) || (origin.Z < b.Min.Z) || (jbyk * b.Min.Z - b.Min.Y + c_zy < 0) || (kbyj * b.Max.Y - b.Max.Z + c_yz > 0)) { return(false); } return(true); case RayType.OPP: if ((origin.X < b.Min.X) || (origin.X > b.Max.X) || (origin.Y > b.Max.Y) || (origin.Z > b.Max.Z) || (jbyk * b.Max.Z - b.Min.Y + c_zy < 0) || (kbyj * b.Max.Y - b.Min.Z + c_yz < 0)) { return(false); } return(true); case RayType.MOM: if ((origin.Y < b.Min.Y) || (origin.Y > b.Max.Y) || (origin.X < b.Min.X) || (origin.Z < b.Min.Z) || (kbyi * b.Min.X - b.Max.Z + c_xz > 0) || (ibyk * b.Min.Z - b.Max.X + c_zx > 0)) { return(false); } return(true); case RayType.MOP: if ((origin.Y < b.Min.Y) || (origin.Y > b.Max.Y) || (origin.X < b.Min.X) || (origin.Z > b.Max.Z) || (kbyi * b.Min.X - b.Min.Z + c_xz < 0) || (ibyk * b.Max.Z - b.Max.X + c_zx > 0)) { return(false); } return(true); case RayType.POM: if ((origin.Y < b.Min.Y) || (origin.Y > b.Max.Y) || (origin.X > b.Max.X) || (origin.Z < b.Min.Z) || (kbyi * b.Max.X - b.Max.Z + c_xz > 0) || (ibyk * b.Min.Z - b.Min.X + c_zx < 0)) { return(false); } return(true); case RayType.POP: if ((origin.Y < b.Min.Y) || (origin.Y > b.Max.Y) || (origin.X > b.Max.X) || (origin.Z > b.Max.Z) || (kbyi * b.Max.X - b.Min.Z + c_xz < 0) || (ibyk * b.Max.Z - b.Min.X + c_zx < 0)) { return(false); } return(true); case RayType.MMO: if ((origin.Z < b.Min.Z) || (origin.Z > b.Max.Z) || (origin.X < b.Min.X) || (origin.Y < b.Min.Y) || (jbyi * b.Min.X - b.Max.Y + c_xy > 0) || (ibyj * b.Min.Y - b.Max.X + c_yx > 0)) { return(false); } return(true); case RayType.MPO: if ((origin.Z < b.Min.Z) || (origin.Z > b.Max.Z) || (origin.X < b.Min.X) || (origin.Y > b.Max.Y) || (jbyi * b.Min.X - b.Min.Y + c_xy < 0) || (ibyj * b.Max.Y - b.Max.X + c_yx > 0)) { return(false); } return(true); case RayType.PMO: if ((origin.Z < b.Min.Z) || (origin.Z > b.Max.Z) || (origin.X > b.Max.X) || (origin.Y < b.Min.Y) || (jbyi * b.Max.X - b.Max.Y + c_xy > 0) || (ibyj * b.Min.Y - b.Min.X + c_yx < 0)) { return(false); } return(true); case RayType.PPO: if ((origin.Z < b.Min.Z) || (origin.Z > b.Max.Z) || (origin.X > b.Max.X) || (origin.Y > b.Max.Y) || (jbyi * b.Max.X - b.Min.Y + c_xy < 0) || (ibyj * b.Max.Y - b.Min.X + c_yx < 0)) { return(false); } return(true); case RayType.MOO: if ((origin.X < b.Min.X) || (origin.Y < b.Min.Y) || (origin.Y > b.Max.Y) || (origin.Z < b.Min.Z) || (origin.Z > b.Max.Z)) { return(false); } return(true); case RayType.POO: if ((origin.X > b.Max.X) || (origin.Y < b.Min.Y) || (origin.Y > b.Max.Y) || (origin.Z < b.Min.Z) || (origin.Z > b.Max.Z)) { return(false); } return(true); case RayType.OMO: if ((origin.Y < b.Min.Y) || (origin.X < b.Min.X) || (origin.X > b.Max.X) || (origin.Z < b.Min.Z) || (origin.Z > b.Max.Z)) { return(false); } if ((origin.Y > b.Max.Y) || (origin.X < b.Min.X) || (origin.X > b.Max.X) || (origin.Z < b.Min.Z) || (origin.Z > b.Max.Z)) { return(false); } if ((origin.Z < b.Min.Z) || (origin.X < b.Min.X) || (origin.X > b.Max.X) || (origin.Y < b.Min.Y) || (origin.Y > b.Max.Y)) { return(false); } if ((origin.Z > b.Max.Z) || (origin.X < b.Min.X) || (origin.X > b.Max.X) || (origin.Y < b.Min.Y) || (origin.Y > b.Max.Y)) { return(false); } return(true); case RayType.OPO: if ((origin.Y > b.Max.Y) || (origin.X < b.Min.X) || (origin.X > b.Max.X) || (origin.Z < b.Min.Z) || (origin.Z > b.Max.Z)) { return(false); } if ((origin.Z < b.Min.Z) || (origin.X < b.Min.X) || (origin.X > b.Max.X) || (origin.Y < b.Min.Y) || (origin.Y > b.Max.Y)) { return(false); } if ((origin.Z > b.Max.Z) || (origin.X < b.Min.X) || (origin.X > b.Max.X) || (origin.Y < b.Min.Y) || (origin.Y > b.Max.Y)) { return(false); } return(true); case RayType.OOM: if ((origin.Z < b.Min.Z) || (origin.X < b.Min.X) || (origin.X > b.Max.X) || (origin.Y < b.Min.Y) || (origin.Y > b.Max.Y)) { return(false); } if ((origin.Z > b.Max.Z) || (origin.X < b.Min.X) || (origin.X > b.Max.X) || (origin.Y < b.Min.Y) || (origin.Y > b.Max.Y)) { return(false); } return(true); case RayType.OOP: if ((origin.Z > b.Max.Z) || (origin.X < b.Min.X) || (origin.X > b.Max.X) || (origin.Y < b.Min.Y) || (origin.Y > b.Max.Y)) { return(false); } return(true); } return(false); }