/// <summary> /// Checks whether the current BoundingBox intersects a Plane. /// </summary> /// <param name="plane">The Plane to check for intersection with.</param> public PlaneIntersectionType Intersects(PlaneD plane) { Vector3D vector3_1; vector3_1.X = (double)plane.Normal.X >= 0.0 ? this.Min.X : this.Max.X; vector3_1.Y = (double)plane.Normal.Y >= 0.0 ? this.Min.Y : this.Max.Y; vector3_1.Z = (double)plane.Normal.Z >= 0.0 ? this.Min.Z : this.Max.Z; Vector3D vector3_2; vector3_2.X = (double)plane.Normal.X >= 0.0 ? this.Max.X : this.Min.X; vector3_2.Y = (double)plane.Normal.Y >= 0.0 ? this.Max.Y : this.Min.Y; vector3_2.Z = (double)plane.Normal.Z >= 0.0 ? this.Max.Z : this.Min.Z; if ((double)plane.Normal.X * (double)vector3_1.X + (double)plane.Normal.Y * (double)vector3_1.Y + (double)plane.Normal.Z * (double)vector3_1.Z + (double)plane.D > 0.0) { return(PlaneIntersectionType.Front); } return((double)plane.Normal.X * (double)vector3_2.X + (double)plane.Normal.Y * (double)vector3_2.Y + (double)plane.Normal.Z * (double)vector3_2.Z + (double)plane.D < 0.0 ? PlaneIntersectionType.Back : PlaneIntersectionType.Intersecting); }
/// <summary> /// Determines whether this Ray intersects a specified Plane. /// </summary> /// <param name="plane">The Plane with which to calculate this Ray's intersection.</param> public double?Intersects(PlaneD plane) { double dot = ((double)plane.Normal.X * (double)this.Direction.X + (double)plane.Normal.Y * (double)this.Direction.Y + (double)plane.Normal.Z * (double)this.Direction.Z); if ((double)Math.Abs(dot) < 9.99999974737875E-06) { return(new double?()); } double originToPosition = (float)((double)plane.Normal.X * (double)this.Position.X + (double)plane.Normal.Y * (double)this.Position.Y + (double)plane.Normal.Z * (double)this.Position.Z); double intersection = (-plane.D - originToPosition) / dot; if ((double)intersection < 0.0) { if ((double)intersection < -9.99999974737875E-06) { return(new double?()); } intersection = 0.0f; } return(new double?(intersection)); }
public PlaneIntersectionType Intersects(PlaneD plane) { Vector3D vectord; Vector3D vectord2; vectord.X = (plane.Normal.X >= 0.0) ? this.Min.X : this.Max.X; vectord.Y = (plane.Normal.Y >= 0.0) ? this.Min.Y : this.Max.Y; vectord.Z = (plane.Normal.Z >= 0.0) ? this.Min.Z : this.Max.Z; if (((((plane.Normal.X * vectord.X) + (plane.Normal.Y * vectord.Y)) + (plane.Normal.Z * vectord.Z)) + plane.D) > 0.0) { return(PlaneIntersectionType.Front); } vectord2.X = (plane.Normal.X >= 0.0) ? this.Max.X : this.Min.X; vectord2.Y = (plane.Normal.Y >= 0.0) ? this.Max.Y : this.Min.Y; vectord2.Z = (plane.Normal.Z >= 0.0) ? this.Max.Z : this.Min.Z; if (((((plane.Normal.X * vectord2.X) + (plane.Normal.Y * vectord2.Y)) + (plane.Normal.Z * vectord2.Z)) + plane.D) >= 0.0) { return(PlaneIntersectionType.Intersecting); } return(PlaneIntersectionType.Back); }
public double?Intersects(PlaneD plane) { double num = ((plane.Normal.X * this.Direction.X) + (plane.Normal.Y * this.Direction.Y)) + (plane.Normal.Z * this.Direction.Z); if (Math.Abs(num) < 9.99999974737875E-06) { return(null); } double num2 = (float)(((plane.Normal.X * this.Position.X) + (plane.Normal.Y * this.Position.Y)) + (plane.Normal.Z * this.Position.Z)); double num3 = (-plane.D - num2) / num; if (num3 < 0.0) { if (num3 < -9.99999974737875E-06) { return(null); } num3 = 0.0; } return(new double?(num3)); }
/// <summary> /// Checks whether the current BoundingFrustumD intersects the specified Plane. /// </summary> /// <param name="plane">The Plane to check for intersection.</param> public PlaneIntersectionType Intersects(PlaneD plane) { int num = 0; for (int index = 0; index < 8; ++index) { double result; Vector3D.Dot(ref this.cornerArray[index], ref plane.Normal, out result); if ((double)result + (double)plane.D > 0.0) { num |= 1; } else { num |= 2; } if (num == 3) { return(PlaneIntersectionType.Intersecting); } } return(num != 1 ? PlaneIntersectionType.Back : PlaneIntersectionType.Front); }
/// <summary> /// Checks whether the current BoundingFrustumD intersects a Plane. /// </summary> /// <param name="plane">The Plane to check for intersection with.</param><param name="result">[OutAttribute] An enumeration indicating whether the BoundingFrustumD intersects the Plane.</param> public void Intersects(ref PlaneD plane, out PlaneIntersectionType result) { int num = 0; for (int index = 0; index < 8; ++index) { double result1; Vector3D.Dot(ref this.cornerArray[index], ref plane.Normal, out result1); if ((double)result1 + (double)plane.D > 0.0) { num |= 1; } else { num |= 2; } if (num == 3) { result = PlaneIntersectionType.Intersecting; return; } } result = num == 1 ? PlaneIntersectionType.Front : PlaneIntersectionType.Back; }
public void Intersects(ref PlaneD plane, out PlaneIntersectionType result) { Vector3D vectord; Vector3D vectord2; vectord.X = (plane.Normal.X >= 0.0) ? this.Min.X : this.Max.X; vectord.Y = (plane.Normal.Y >= 0.0) ? this.Min.Y : this.Max.Y; vectord.Z = (plane.Normal.Z >= 0.0) ? this.Min.Z : this.Max.Z; vectord2.X = (plane.Normal.X >= 0.0) ? this.Max.X : this.Min.X; vectord2.Y = (plane.Normal.Y >= 0.0) ? this.Max.Y : this.Min.Y; vectord2.Z = (plane.Normal.Z >= 0.0) ? this.Max.Z : this.Min.Z; if (((((plane.Normal.X * vectord.X) + (plane.Normal.Y * vectord.Y)) + (plane.Normal.Z * vectord.Z)) + plane.D) > 0.0) { result = PlaneIntersectionType.Front; } else if (((((plane.Normal.X * vectord2.X) + (plane.Normal.Y * vectord2.Y)) + (plane.Normal.Z * vectord2.Z)) + plane.D) < 0.0) { result = PlaneIntersectionType.Back; } else { result = PlaneIntersectionType.Intersecting; } }
public void Intersects(ref PlaneD plane, out PlaneIntersectionType result) { int num = 0; for (int i = 0; i < 8; i++) { double num3; Vector3D.Dot(ref this.cornerArray[i], ref plane.Normal, out num3); if ((num3 + plane.D) > 0.0) { num |= 1; } else { num |= 2; } if (num == 3) { result = PlaneIntersectionType.Intersecting; return; } } result = (num == 1) ? PlaneIntersectionType.Front : PlaneIntersectionType.Back; }
public void Intersects(ref PlaneD plane, out double?result) { double num = ((plane.Normal.X * this.Direction.X) + (plane.Normal.Y * this.Direction.Y)) + (plane.Normal.Z * this.Direction.Z); if (Math.Abs(num) < 9.99999974737875E-06) { result = 0; } else { double num2 = ((plane.Normal.X * this.Position.X) + (plane.Normal.Y * this.Position.Y)) + (plane.Normal.Z * this.Position.Z); double num3 = (-plane.D - num2) / num; if (num3 < 0.0) { if (num3 < -9.99999974737875E-06) { result = 0; return; } result = 0.0; } result = new double?(num3); } }
private static Vector3D ComputeIntersection(ref PlaneD plane, ref RayD ray) { double num = (-plane.D - Vector3D.Dot(plane.Normal, ray.Position)) / Vector3D.Dot(plane.Normal, ray.Direction); return(ray.Position + ray.Direction * num); }
public bool IntersectsTriangle(ref Vector3D v0, ref Vector3D v1, ref Vector3D v2) { Vector3D vectord; Vector3D vectord2; Vector3D vectord5; double num; PlaneIntersectionType type; Vector3D.Min(ref v0, ref v1, out vectord); Vector3D.Min(ref vectord, ref v2, out vectord); Vector3D.Max(ref v0, ref v1, out vectord2); Vector3D.Max(ref vectord2, ref v2, out vectord2); if (vectord.X > this.Max.X) { return(false); } if (vectord2.X < this.Min.X) { return(false); } if (vectord.Y > this.Max.Y) { return(false); } if (vectord2.Y < this.Min.Y) { return(false); } if (vectord.Z > this.Max.Z) { return(false); } if (vectord2.Z < this.Min.Z) { return(false); } Vector3D vectord3 = v1 - v0; Vector3D vectord4 = v2 - v1; Vector3D.Cross(ref vectord3, ref vectord4, out vectord5); Vector3D.Dot(ref v0, ref vectord5, out num); PlaneD plane = new PlaneD(vectord5, -num); this.Intersects(ref plane, out type); switch (type) { case PlaneIntersectionType.Back: return(false); case PlaneIntersectionType.Front: return(false); } Vector3D center = this.Center; BoundingBoxD xd = new BoundingBoxD(this.Min - center, this.Max - center); Vector3D halfExtents = xd.HalfExtents; Vector3D vectord8 = v0 - v2; Vector3D vectord9 = v0 - center; Vector3D vectord10 = v1 - center; Vector3D vectord11 = v2 - center; double num2 = (halfExtents.Y * Math.Abs(vectord3.Z)) + (halfExtents.Z * Math.Abs(vectord3.Y)); double num3 = (vectord9.Z * vectord10.Y) - (vectord9.Y * vectord10.Z); double num5 = (vectord11.Z * vectord3.Y) - (vectord11.Y * vectord3.Z); if ((Math.Min(num3, num5) > num2) || (Math.Max(num3, num5) < -num2)) { return(false); } num2 = (halfExtents.X * Math.Abs(vectord3.Z)) + (halfExtents.Z * Math.Abs(vectord3.X)); num3 = (vectord9.X * vectord10.Z) - (vectord9.Z * vectord10.X); num5 = (vectord11.X * vectord3.Z) - (vectord11.Z * vectord3.X); if ((Math.Min(num3, num5) > num2) || (Math.Max(num3, num5) < -num2)) { return(false); } num2 = (halfExtents.X * Math.Abs(vectord3.Y)) + (halfExtents.Y * Math.Abs(vectord3.X)); num3 = (vectord9.Y * vectord10.X) - (vectord9.X * vectord10.Y); num5 = (vectord11.Y * vectord3.X) - (vectord11.X * vectord3.Y); if ((Math.Min(num3, num5) > num2) || (Math.Max(num3, num5) < -num2)) { return(false); } num2 = (halfExtents.Y * Math.Abs(vectord4.Z)) + (halfExtents.Z * Math.Abs(vectord4.Y)); double num4 = (vectord10.Z * vectord11.Y) - (vectord10.Y * vectord11.Z); num3 = (vectord9.Z * vectord4.Y) - (vectord9.Y * vectord4.Z); if ((Math.Min(num4, num3) > num2) || (Math.Max(num4, num3) < -num2)) { return(false); } num2 = (halfExtents.X * Math.Abs(vectord4.Z)) + (halfExtents.Z * Math.Abs(vectord4.X)); num4 = (vectord10.X * vectord11.Z) - (vectord10.Z * vectord11.X); num3 = (vectord9.X * vectord4.Z) - (vectord9.Z * vectord4.X); if ((Math.Min(num4, num3) > num2) || (Math.Max(num4, num3) < -num2)) { return(false); } num2 = (halfExtents.X * Math.Abs(vectord4.Y)) + (halfExtents.Y * Math.Abs(vectord4.X)); num4 = (vectord10.Y * vectord11.X) - (vectord10.X * vectord11.Y); num3 = (vectord9.Y * vectord4.X) - (vectord9.X * vectord4.Y); if ((Math.Min(num4, num3) > num2) || (Math.Max(num4, num3) < -num2)) { return(false); } num2 = (halfExtents.Y * Math.Abs(vectord8.Z)) + (halfExtents.Z * Math.Abs(vectord8.Y)); num5 = (vectord11.Z * vectord9.Y) - (vectord11.Y * vectord9.Z); num4 = (vectord10.Z * vectord8.Y) - (vectord10.Y * vectord8.Z); if ((Math.Min(num5, num4) > num2) || (Math.Max(num5, num4) < -num2)) { return(false); } num2 = (halfExtents.X * Math.Abs(vectord8.Z)) + (halfExtents.Z * Math.Abs(vectord8.X)); num5 = (vectord11.X * vectord9.Z) - (vectord11.Z * vectord9.X); num4 = (vectord10.X * vectord8.Z) - (vectord10.Z * vectord8.X); if ((Math.Min(num5, num4) > num2) || (Math.Max(num5, num4) < -num2)) { return(false); } num2 = (halfExtents.X * Math.Abs(vectord8.Y)) + (halfExtents.Y * Math.Abs(vectord8.X)); num5 = (vectord11.Y * vectord9.X) - (vectord11.X * vectord9.Y); num4 = (vectord10.Y * vectord8.X) - (vectord10.X * vectord8.Y); return((Math.Min(num5, num4) <= num2) && (Math.Max(num5, num4) >= -num2)); }
public bool IntersectsTriangle(ref Vector3D v0, ref Vector3D v1, ref Vector3D v2) { // This code is based on: Akenine-Moeller, Thomas - "Fast 3D Triangle-Box Overlap Testing" // Test 1) - Separation of triangle and BB by the bounding box's 6 planes Vector3D min, max; Vector3D.Min(ref v0, ref v1, out min); Vector3D.Min(ref min, ref v2, out min); Vector3D.Max(ref v0, ref v1, out max); Vector3D.Max(ref max, ref v2, out max); if (min.X > Max.X) { return(false); } if (max.X < Min.X) { return(false); } if (min.Y > Max.Y) { return(false); } if (max.Y < Min.Y) { return(false); } if (min.Z > Max.Z) { return(false); } if (max.Z < Min.Z) { return(false); } // Test 2) - Separation by the triangle's plane Vector3D f0 = v1 - v0; Vector3D f1 = v2 - v1; Vector3D triN; Vector3D.Cross(ref f0, ref f1, out triN); double d; Vector3D.Dot(ref v0, ref triN, out d); // The triangle's plane. It does not have to be normalized PlaneD triPlane = new PlaneD(triN, -d); PlaneIntersectionType intersection; Intersects(ref triPlane, out intersection); if (intersection == PlaneIntersectionType.Back) { return(false); } if (intersection == PlaneIntersectionType.Front) { return(false); } // Test 3) - Separation by planes that are perpendicular to coordinate axes e0, e1, e2 and triangle edges f0, f1, f2 Vector3D center = Center; BoundingBoxD tmpBox = new BoundingBoxD(Min - center, Max - center); Vector3D originHalf = tmpBox.HalfExtents; Vector3D f2 = v0 - v2; Vector3D v0sh = v0 - center; Vector3D v1sh = v1 - center; Vector3D v2sh = v2 - center; double boxR, p0, p1, p2; // Does a plane that has axis e0 x f0 separate the triangle and BB? boxR = originHalf.Y * Math.Abs(f0.Z) + originHalf.Z * Math.Abs(f0.Y); // "Radius" of the BB, if moved to the origin p0 = v0sh.Z * v1sh.Y - v0sh.Y * v1sh.Z; // Projection of v0sh and also v1sh (axis is perpendicular on f0 = v1sh - v0sh) onto the axis p2 = v2sh.Z * f0.Y - v2sh.Y * f0.Z; // Projection of v2sh on the axis if (Math.Min(p0, p2) > boxR || Math.Max(p0, p2) < -boxR) { return(false); // Now we can test projection of the triangle against the projection of the BB (which is (-boxR, +boxR)) } // Now for the remaining 8 combinations...: // e1 x f0 boxR = originHalf.X * Math.Abs(f0.Z) + originHalf.Z * Math.Abs(f0.X); p0 = v0sh.X * v1sh.Z - v0sh.Z * v1sh.X; p2 = v2sh.X * f0.Z - v2sh.Z * f0.X; if (Math.Min(p0, p2) > boxR || Math.Max(p0, p2) < -boxR) { return(false); } // e2 x f0 boxR = originHalf.X * Math.Abs(f0.Y) + originHalf.Y * Math.Abs(f0.X); p0 = v0sh.Y * v1sh.X - v0sh.X * v1sh.Y; p2 = v2sh.Y * f0.X - v2sh.X * f0.Y; if (Math.Min(p0, p2) > boxR || Math.Max(p0, p2) < -boxR) { return(false); } // e0 x f1 boxR = originHalf.Y * Math.Abs(f1.Z) + originHalf.Z * Math.Abs(f1.Y); p1 = v1sh.Z * v2sh.Y - v1sh.Y * v2sh.Z; p0 = v0sh.Z * f1.Y - v0sh.Y * f1.Z; if (Math.Min(p1, p0) > boxR || Math.Max(p1, p0) < -boxR) { return(false); } // e1 x f1 boxR = originHalf.X * Math.Abs(f1.Z) + originHalf.Z * Math.Abs(f1.X); p1 = v1sh.X * v2sh.Z - v1sh.Z * v2sh.X; p0 = v0sh.X * f1.Z - v0sh.Z * f1.X; if (Math.Min(p1, p0) > boxR || Math.Max(p1, p0) < -boxR) { return(false); } // e2 x f1 boxR = originHalf.X * Math.Abs(f1.Y) + originHalf.Y * Math.Abs(f1.X); p1 = v1sh.Y * v2sh.X - v1sh.X * v2sh.Y; p0 = v0sh.Y * f1.X - v0sh.X * f1.Y; if (Math.Min(p1, p0) > boxR || Math.Max(p1, p0) < -boxR) { return(false); } // e0 x f2 boxR = originHalf.Y * Math.Abs(f2.Z) + originHalf.Z * Math.Abs(f2.Y); p2 = v2sh.Z * v0sh.Y - v2sh.Y * v0sh.Z; p1 = v1sh.Z * f2.Y - v1sh.Y * f2.Z; if (Math.Min(p2, p1) > boxR || Math.Max(p2, p1) < -boxR) { return(false); } // e1 x f2 boxR = originHalf.X * Math.Abs(f2.Z) + originHalf.Z * Math.Abs(f2.X); p2 = v2sh.X * v0sh.Z - v2sh.Z * v0sh.X; p1 = v1sh.X * f2.Z - v1sh.Z * f2.X; if (Math.Min(p2, p1) > boxR || Math.Max(p2, p1) < -boxR) { return(false); } // e2 x f2 boxR = originHalf.X * Math.Abs(f2.Y) + originHalf.Y * Math.Abs(f2.X); p2 = v2sh.Y * v0sh.X - v2sh.X * v0sh.Y; p1 = v1sh.Y * f2.X - v1sh.X * f2.Y; if (Math.Min(p2, p1) > boxR || Math.Max(p2, p1) < -boxR) { return(false); } return(true); }