// calculate culling planes from portal and frustum
// origin and add to list of culling planes
// NOTE: returns 0 if portal was completely culled by existing planes
// returns > 0 if culling planes are added (# is planes added)
public int AddPortalCullingPlanes(Portal portal)
{
int addedcullingplanes = 0;
// If portal is of type aabb or sphere, add a plane which is same as frustum
// origin plane (ie. redundant). We do this because we need the plane as a flag
// to prevent infinite recursion
if (portal.Type == PORTAL_TYPE.PORTAL_TYPE_AABB || portal.Type == PORTAL_TYPE.PORTAL_TYPE_SPHERE)
{
PCPlane newPlane = GetUnusedCullingPlane();
newPlane.SetFromAxiomPlane(this.mOriginPlane);
newPlane.Portal = portal;
this.mActiveCullingPlanes.Add(newPlane);
addedcullingplanes++;
return(addedcullingplanes);
}
// For portal Quads: Up to 4 planes can be added by the sides of a portal quad.
// Each plane is created from 2 corners (world space) of the portal and the
// frustum origin (world space).
int i, j;
PlaneSide pt0_side, pt1_side;
bool visible;
for (i = 0; i < 4; i++)
{
// first check if both corners are outside of one of the existing planes
j = i + 1;
if (j > 3)
{
j = 0;
}
visible = true;
foreach (PCPlane plane in this.mActiveCullingPlanes)
{
pt0_side = plane.GetSide(portal.getDerivedCorner(i));
pt1_side = plane.GetSide(portal.getDerivedCorner(j));
if (pt0_side == PlaneSide.Negative && pt1_side == PlaneSide.Negative)
{
// the portal edge was actually completely culled by one of culling planes
visible = false;
}
}
if (visible)
{
// add the plane created from the two portal corner points and the frustum location
// to the culling plane
PCPlane newPlane = GetUnusedCullingPlane();
if (this.projType == Projection.Orthographic) // use camera direction if projection is orthographic.
{
newPlane.Redefine(portal.getDerivedCorner(j) + this.mOriginPlane.Normal, portal.getDerivedCorner(j),
portal.getDerivedCorner(i));
}
else
{
newPlane.Redefine(this.mOrigin, portal.getDerivedCorner(j), portal.getDerivedCorner(i));
}
newPlane.Portal = portal;
this.mActiveCullingPlanes.Add(newPlane);
addedcullingplanes++;
}
}
// if we added ANY planes from the quad portal, we should add the plane of the
// portal itself as an additional culling plane.
if (addedcullingplanes > 0)
{
PCPlane newPlane = GetUnusedCullingPlane();
newPlane.Redefine(portal.getDerivedCorner(2), portal.getDerivedCorner(1), portal.getDerivedCorner(0));
newPlane.Portal = portal;
this.mActiveCullingPlanes.Add(newPlane);
addedcullingplanes++;
}
return(addedcullingplanes);
}