public void GetCameraToViewportBoxVolume(Real screenLeft, Real screenTop, Real screenRight, Real screenBottom,
PlaneBoundedVolume outVolume, bool includeFarPlane)
{
outVolume.planes.Clear();
if (ProjectionType == Projection.Perspective)
{
// Use the corner rays to generate planes
var ul = GetCameraToViewportRay(screenLeft, screenTop);
var ur = GetCameraToViewportRay(screenRight, screenTop);
var bl = GetCameraToViewportRay(screenLeft, screenBottom);
var br = GetCameraToViewportRay(screenRight, screenBottom);
// top plane
var normal = ul.Direction.Cross(ur.Direction);
normal.Normalize();
outVolume.planes.Add(new Plane(normal, DerivedPosition));
// right plane
normal = ur.Direction.Cross(br.Direction);
normal.Normalize();
outVolume.planes.Add(new Plane(normal, DerivedPosition));
// bottom plane
normal = br.Direction.Cross(bl.Direction);
normal.Normalize();
outVolume.planes.Add(new Plane(normal, DerivedPosition));
// left plane
normal = bl.Direction.Cross(ul.Direction);
normal.Normalize();
outVolume.planes.Add(new Plane(normal, DerivedPosition));
}
else
{
// ortho planes are parallel to frustum planes
var ul = GetCameraToViewportRay(screenLeft, screenTop);
var br = GetCameraToViewportRay(screenRight, screenBottom);
UpdateFrustumPlanes();
outVolume.planes.Add(new Plane(FrustumPlanes[(int)FrustumPlane.Top].Normal, ul.Origin));
outVolume.planes.Add(new Plane(FrustumPlanes[(int)FrustumPlane.Right].Normal, br.Origin));
outVolume.planes.Add(new Plane(FrustumPlanes[(int)FrustumPlane.Bottom].Normal, br.Origin));
outVolume.planes.Add(new Plane(FrustumPlanes[(int)FrustumPlane.Left].Normal, ul.Origin));
}
// near/far planes applicable to both projection types
outVolume.planes.Add(new Plane(FrustumPlanes[(int)FrustumPlane.Near]));
if (includeFarPlane)
outVolume.planes.Add(new Plane(FrustumPlanes[(int)FrustumPlane.Far]));
}