private BoundingVolume BuildFrustumFromViewport(Viewport3DHitTestHelper.ViewportInformation viewport, List <Point> frustumOutline)
        {
            List <Ray3D> list1  = new List <Ray3D>(frustumOutline.Count);
            Point        point1 = new Point(0.0, 0.0);

            for (int index = 0; index < frustumOutline.Count; ++index)
            {
                list1.Add(CameraRayHelpers.RayFromViewportPoint(viewport.Bounds, viewport.Camera, frustumOutline[index]));
                point1 += (Vector)frustumOutline[index];
            }
            Point          point2  = (Point)Vector.Divide((Vector)point1, (double)frustumOutline.Count);
            Point3D        point3D = new Point3D(0.0, 0.0, 0.0);
            List <Plane3D> list2   = new List <Plane3D>();

            for (int index = 0; index < frustumOutline.Count; ++index)
            {
                Vector3D normal = Vector3D.AngleBetween(list1[index].Direction, list1[(index + 1) % frustumOutline.Count].Direction) <= 0.0001 ? Vector3D.CrossProduct(list1[index].Direction, list1[(index + 1) % frustumOutline.Count].Origin - list1[index].Origin) : Vector3D.CrossProduct(list1[index].Direction, list1[(index + 1) % frustumOutline.Count].Direction);
                normal.Normalize();
                list2.Add(new Plane3D(normal, list1[index].Origin));
                point3D += (Vector3D)list1[index].Origin;
            }
            bool           flag           = list2[0].GetSignedDistanceFromPoint(list1[2].Origin) < 0.0;
            BoundingVolume boundingVolume = new BoundingVolume();

            for (int index = 0; index < frustumOutline.Count; ++index)
            {
                Plane3D frustumSide = list2[index];
                if (flag)
                {
                    Vector3D normal = frustumSide.Normal;
                    normal.Negate();
                    frustumSide = new Plane3D(normal, list1[index].Origin);
                }
                boundingVolume.AddSide(frustumSide);
            }
            Ray3D ray3D = CameraRayHelpers.RayFromViewportPoint(viewport.Bounds, viewport.Camera, point2);

            this.frustumCenterRay = new Ray3D((Point3D)Vector3D.Divide((Vector3D)point3D, (double)frustumOutline.Count), ray3D.Direction);
            ProjectionCamera projectionCamera = viewport.Camera as ProjectionCamera;

            if (projectionCamera != null)
            {
                boundingVolume.NearFrustum = new Plane3D(ray3D.Direction, this.frustumCenterRay.Origin);
                if (!double.IsPositiveInfinity(projectionCamera.FarPlaneDistance))
                {
                    Vector3D direction = ray3D.Direction;
                    direction.Negate();
                    boundingVolume.FarFrustum = new Plane3D(direction, this.frustumCenterRay.Origin + (projectionCamera.FarPlaneDistance - projectionCamera.NearPlaneDistance) * ray3D.Direction);
                }
            }
            return(boundingVolume);
        }
 public ViewportInformation(Viewport3D viewport, GeneralTransform transform)
 {
     this = new Viewport3DHitTestHelper.ViewportInformation(viewport.Children, viewport.Camera, new Size(viewport.ActualWidth, viewport.ActualHeight), transform);
 }