public VoxelChunk(int _chunkX, int _chunkZ, int _width, int _height, int _depth) { chunkX = _chunkX; chunkZ = _chunkZ; width = _width; height = _height; depth = _depth; bounds = new AxisAlignedBoundingBox(new Vector3(chunkX * width, 0, chunkZ * depth), new Vector3((chunkX + 1) * width, height, (chunkZ + 1) * depth)); translationMatrix = Matrix4.CreateTranslation(new Vector3(chunkX * width, 0, chunkZ * depth)); meshBuilt = false; data = new ushort[width, height, depth]; }
/// <summary> /// True if the AxisAlignedBoundingBox is in (or partially in) the Frustum /// </summary> /// <param name="b">AxixAlignedBoundingBox to check</param> /// <returns>True if an intersection exists</returns> public bool Intersects(AxisAlignedBoundingBox box) { for (int i = 0; i < 6; i++) { Plane p = planes[i]; float d = box.Center.Dot(p.Normal); float r = box.Size.x * Math.Abs(p.Normal.x) + box.Size.y * Math.Abs(p.Normal.y) + box.Size.z * Math.Abs(p.Normal.z); float dpr = d + r; float dmr = d - r; if (dpr < -p.Scalar) return false; } return true; }
/// <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; }
/// <summary> /// Creates an orientated bounding box of size min, max /// </summary> /// <param name="Min">Minimum x,y,z</param> /// <param name="Max">Maximum x,y,z</param> public OrientatedBoundingBox(Vector3 Min, Vector3 Max) { box = new AxisAlignedBoundingBox(Min, Max); modelMatrix = Matrix4.Identity; }
/// <summary> /// Check which side a AxisAlignedBoundingBox falls to on the plane /// </summary> /// <param name="b">AxisAlignedBoundingBox</param> /// <returns>PlaneSide.Negative, PlaneSide.Positive or PlaneSide.Both</returns> public PlaneSide Intersects(AxisAlignedBoundingBox b) { float t_distance = DistanceFromPoint(b.Center); float t_mdist = Math.Abs(Vector3.Dot(normal, b.Size * 0.5f)); if (t_distance < -t_mdist) return PlaneSide.Negative; else if (t_distance > t_mdist) return PlaneSide.Positive; else return PlaneSide.Both; }
/// <summary> /// Returns true if the AxisAlignedBoundingBox intersects this AxisAlignedBoundingBox /// </summary> /// <param name="b">AxisAlignedBoundingBox to test in this AxisAlignedBoundingBox</param> /// <returns>True if the AxisAlignedBoundingBox intersects this AxisAlignedBoundingBox</returns> public bool Intersects(AxisAlignedBoundingBox b) { // Test the six planes of the box if (max.x < b.Min.x) return false; if (max.y < b.Min.y) return false; if (max.z < b.Min.z) return false; if (min.x > b.Max.x) return false; if (min.y > b.Max.y) return false; if (min.z > b.Max.z) return false; // Must be intersecting if all planes check out return true; }
/// <summary> /// Returns the intersection of the two AxisAlignedBoundingBox objects if an intersection exists /// </summary> /// <param name="b">AxisAlignedBoundingBox to intersect with this AxisAlignedBoundingBox</param> /// <returns>The intersection of the two AxisAlignedBoundingBox objects</returns> public AxisAlignedBoundingBox Intersection(AxisAlignedBoundingBox b) { Vector3 t_min = min; Vector3 t_max = max; t_min.TakeMax(b.Min); t_max.TakeMin(b.Max); if (t_min.x < t_max.x && t_min.y < t_max.y && t_min.z < t_max.z) return new AxisAlignedBoundingBox(t_min, t_max); return null; // Must be no intersection }
/// <summary> /// Increase the size of the bounding box (if needed) to fit the AxisAlignedBoundingBox /// </summary> /// <param name="Box">The AxisAlignedBoundingBox to fit into this AxisAlignedBoundingBox</param> public void AddBoundingBox(AxisAlignedBoundingBox Box) { min.TakeMin(Box.Min); max.TakeMax(Box.Max); }
/// <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); }
/// <summary> /// Creates an orientated bounding box of size min, max. /// </summary> /// <param name="Min">Minimum x, y, z.</param> /// <param name="Max">Maximum x, y, z.</param> public OrientatedBoundingBox(Vector3 Min, Vector3 Max) { box = new AxisAlignedBoundingBox(Min, Max); modelMatrix = Matrix4.Identity; }
/// <summary> /// Increase the size of the bounding box (if needed) to fit the AxisAlignedBoundingBox. /// </summary> /// <param name="Box">The AxisAlignedBoundingBox to fit into this AxisAlignedBoundingBox.</param> public void AddBoundingBox(AxisAlignedBoundingBox Box) { min.TakeMin(Box.Min); max.TakeMax(Box.Max); }
/// <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); }