public unsafe ContainmentType Contains(ref BoundingFrustum other)
        {
            int            pointsContained = 0;
            FrustumCorners corners         = other.GetCorners();
            Vector3 *      cornersPtr      = (Vector3 *)&corners;

            for (int i = 0; i < 8; i++)
            {
                if (Contains(cornersPtr[i]) != ContainmentType.Disjoint)
                {
                    pointsContained++;
                }
            }

            if (pointsContained == 8)
            {
                return(ContainmentType.Contains);
            }
            else if (pointsContained == 0)
            {
                return(ContainmentType.Disjoint);
            }
            else
            {
                return(ContainmentType.Intersects);
            }
        }
Esempio n. 2
0
        public static void ComputePerspectiveFrustumCorners(
            ref Vector3 viewPosition,
            ref Vector3 viewDirection,
            ref Vector3 globalUpDirection,
            float fov,
            float nearDistance,
            float farDistance,
            float aspectRatio,
            out FrustumCorners corners)
        {
            float nearHeight = (float)(2 * Math.Tan(fov / 2.0) * nearDistance);
            float nearWidth  = nearHeight * aspectRatio;
            float farHeight  = (float)(2 * Math.Tan(fov / 2.0) * farDistance);
            float farWidth   = farHeight * aspectRatio;

            Vector3 right = Vector3.Normalize(Vector3.Cross(viewDirection, globalUpDirection));
            Vector3 up    = Vector3.Normalize(Vector3.Cross(right, viewDirection));

            Vector3 nearCenter = viewPosition + viewDirection * nearDistance;
            Vector3 farCenter  = viewPosition + viewDirection * farDistance;

            corners.NearTopLeft     = nearCenter - ((nearWidth / 2f) * right) + ((nearHeight / 2) * up);
            corners.NearTopRight    = nearCenter + ((nearWidth / 2f) * right) + ((nearHeight / 2) * up);
            corners.NearBottomLeft  = nearCenter - ((nearWidth / 2f) * right) - ((nearHeight / 2) * up);
            corners.NearBottomRight = nearCenter + ((nearWidth / 2f) * right) - ((nearHeight / 2) * up);

            corners.FarTopLeft     = farCenter - ((farWidth / 2f) * right) + ((farHeight / 2) * up);
            corners.FarTopRight    = farCenter + ((farWidth / 2f) * right) + ((farHeight / 2) * up);
            corners.FarBottomLeft  = farCenter - ((farWidth / 2f) * right) - ((farHeight / 2) * up);
            corners.FarBottomRight = farCenter + ((farWidth / 2f) * right) - ((farHeight / 2) * up);
        }
Esempio n. 3
0
        public static void GetCorners(float eyeX, float eyeY, float eyeZ, float viewX, float viewY, float viewZ)
        {
            Vector3         viewOrigin      = new Vector3(eyeX, eyeY, eyeZ);
            Vector3         viewDir         = Vector3.Normalize(new Vector3(viewX, viewY, viewZ));
            Matrix4x4       view            = Matrix4x4.CreateLookAt(viewOrigin, viewDir, Vector3.UnitY);
            const float     nearDist        = 2f;
            const float     farDist         = 10f;
            const float     fov             = 1.0f;
            const float     ratio           = 1.0f;
            Matrix4x4       perspectiveProj = Matrix4x4.CreatePerspectiveFieldOfView(fov, ratio, nearDist, farDist);
            BoundingFrustum frustum         = new BoundingFrustum(view * perspectiveProj);

            FrustumCorners corners        = frustum.GetCorners();
            Vector3        nearCenter     = viewOrigin + viewDir * nearDist;
            float          nearHalfHeight = (float)Math.Tan(fov / 2f) * nearDist;
            float          nearHalfWidth  = nearHalfHeight * ratio;
            Vector3        up             = Vector3.Transform(Vector3.UnitY, view);
            Vector3        right          = -Vector3.Cross(up, viewDir);

            FuzzyComparer fuzzyComparer = new FuzzyComparer();

            AssertEqual(nearCenter - nearHalfWidth * right + nearHalfHeight * up, corners.NearTopLeft, fuzzyComparer);
            AssertEqual(nearCenter + nearHalfWidth * right + nearHalfHeight * up, corners.NearTopRight, fuzzyComparer);
            AssertEqual(nearCenter - nearHalfWidth * right - nearHalfHeight * up, corners.NearBottomLeft, fuzzyComparer);
            AssertEqual(nearCenter + nearHalfWidth * right - nearHalfHeight * up, corners.NearBottomRight, fuzzyComparer);

            Vector3 farCenter     = viewOrigin + viewDir * farDist;
            float   farHalfHeight = (float)Math.Tan(fov / 2f) * farDist;
            float   farHalfWidth  = farHalfHeight * ratio;

            AssertEqual(farCenter - farHalfWidth * right + farHalfHeight * up, corners.FarTopLeft, fuzzyComparer);
            AssertEqual(farCenter + farHalfWidth * right + farHalfHeight * up, corners.FarTopRight, fuzzyComparer);
            AssertEqual(farCenter - farHalfWidth * right - farHalfHeight * up, corners.FarBottomLeft, fuzzyComparer);
            AssertEqual(farCenter + farHalfWidth * right - farHalfHeight * up, corners.FarBottomRight, fuzzyComparer);
        }
 public void GetCorners(out FrustumCorners corners)
 {
     PlaneIntersection(ref _planes.Near, ref _planes.Top, ref _planes.Left, out corners.NearTopLeft);
     PlaneIntersection(ref _planes.Near, ref _planes.Top, ref _planes.Right, out corners.NearTopRight);
     PlaneIntersection(ref _planes.Near, ref _planes.Bottom, ref _planes.Left, out corners.NearBottomLeft);
     PlaneIntersection(ref _planes.Near, ref _planes.Bottom, ref _planes.Right, out corners.NearBottomRight);
     PlaneIntersection(ref _planes.Far, ref _planes.Top, ref _planes.Left, out corners.FarTopLeft);
     PlaneIntersection(ref _planes.Far, ref _planes.Top, ref _planes.Right, out corners.FarTopRight);
     PlaneIntersection(ref _planes.Far, ref _planes.Bottom, ref _planes.Left, out corners.FarBottomLeft);
     PlaneIntersection(ref _planes.Far, ref _planes.Bottom, ref _planes.Right, out corners.FarBottomRight);
 }
Esempio n. 5
0
        public static unsafe void ComputeOrthographicBoundsForPerpectiveFrustum(
            ref FrustumCorners corners,
            ref Vector3 lightDir,
            float cameraFarDistance,
            out Matrix4x4 lightView,
            out OrthographicBounds bounds)
        {
            float   nearClipOffset = 40.0f;
            Vector3 centroid       =
                (corners.NearTopLeft + corners.NearTopRight + corners.NearBottomLeft + corners.NearBottomRight
                 + corners.FarTopLeft + corners.FarTopRight + corners.FarBottomLeft + corners.FarBottomRight)
                / 8f;
            Vector3 lightOrigin = centroid - (lightDir * (cameraFarDistance + nearClipOffset));

            lightView = Matrix4x4.CreateLookAt(lightOrigin, centroid, Vector3.UnitY);

            float *  lightSpaceCornerFloats = stackalloc float[3 * 8];
            Vector3 *lightSpaceCorners      = (Vector3 *)lightSpaceCornerFloats;

            // Light-view-space
            lightSpaceCorners[0] = Vector3.Transform(corners.NearTopLeft, lightView);
            lightSpaceCorners[1] = Vector3.Transform(corners.NearTopRight, lightView);
            lightSpaceCorners[2] = Vector3.Transform(corners.NearBottomLeft, lightView);
            lightSpaceCorners[3] = Vector3.Transform(corners.NearBottomRight, lightView);

            lightSpaceCorners[4] = Vector3.Transform(corners.FarTopLeft, lightView);
            lightSpaceCorners[5] = Vector3.Transform(corners.FarTopRight, lightView);
            lightSpaceCorners[6] = Vector3.Transform(corners.FarBottomLeft, lightView);
            lightSpaceCorners[7] = Vector3.Transform(corners.FarBottomRight, lightView);

            bounds.MinX = lightSpaceCorners[0].X;
            bounds.MaxX = lightSpaceCorners[0].X;
            bounds.MinY = lightSpaceCorners[0].Y;
            bounds.MaxY = lightSpaceCorners[0].Y;
            bounds.MinZ = lightSpaceCorners[0].Z;
            bounds.MaxZ = lightSpaceCorners[0].Z;

            for (int i = 1; i < 8; i++)
            {
                if (lightSpaceCorners[i].X < bounds.MinX)
                {
                    bounds.MinX = lightSpaceCorners[i].X;
                }
                if (lightSpaceCorners[i].X > bounds.MaxX)
                {
                    bounds.MaxX = lightSpaceCorners[i].X;
                }

                if (lightSpaceCorners[i].Y < bounds.MinY)
                {
                    bounds.MinY = lightSpaceCorners[i].Y;
                }
                if (lightSpaceCorners[i].Y > bounds.MaxY)
                {
                    bounds.MaxY = lightSpaceCorners[i].Y;
                }

                if (lightSpaceCorners[i].Z < bounds.MinZ)
                {
                    bounds.MinZ = lightSpaceCorners[i].Z;
                }
                if (lightSpaceCorners[i].Z > bounds.MaxZ)
                {
                    bounds.MaxZ = lightSpaceCorners[i].Z;
                }
            }
        }