Пример #1
0
        /// <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);
        }
Пример #2
0
        /// <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));
        }
Пример #3
0
        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);
        }
Пример #4
0
        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));
        }
Пример #5
0
        /// <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);
        }
Пример #6
0
        /// <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;
        }
Пример #7
0
        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;
            }
        }
Пример #8
0
        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;
        }
Пример #9
0
        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);
            }
        }
Пример #10
0
        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);
        }
Пример #11
0
        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));
        }
Пример #12
0
        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);
        }