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); }